shaggy17goo
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # W2 MQTT Lab #### Autorzy: Paweł Gryka, Michał Wawrzyńczak [TOC] # Ćwiczenie 1 ## 1.1. W programie Wireshark włącz przechwytywanie na właściwym interfejsie sieciowym ## 1.2. Korzystając z aplikacji okienkowej np. MQTT Explorer: ### 1.2.1. Ustaw nasłuchiwanie komunikatów w tematacie `/w2mqqt/+` ![image](https://hackmd.io/_uploads/r12qhGDHp.png) ### 1.2.2. Nadaj kilka przykładowych komunikatów w temacie odpowiadającym numerowi Twojego zespołu `(zespol_003)` ![image](https://hackmd.io/_uploads/ByQFTzvHT.png) ![image](https://hackmd.io/_uploads/H1gdazPS6.png) ### 1.2.3. Rozłącz klienta MQTT ## 1.3. Umieść w protokole zrzuty z Wiresharka pokazujące dane pakiety, dokładnie zinterpretuj je dla warstw warstw L3, L4 i L7 ![image](https://hackmd.io/_uploads/rJYNymwH6.png) ### 1.3.1. CONNECT ![image](https://hackmd.io/_uploads/ryJkJQvr6.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Connect Command - *Długość wiadomości:* 34 bajty - *Nazwa protokołu:* MQTT - *Wersja protokołu:* MQTT v3.1.1 - *Flagi połączenia:* - *Clean Session Flag:* Ustawione na 1, co oznacza, że sesja jest czysta, a poprzednie dane sesji powinny zostać usunięte. - *QoS Level:* Ustawione na 0, co oznacza, że używane jest "At most once delivery" (Fire and Forget). - *Keep Alive:* Ustawione na 60, co oznacza, że klient musi utrzymać połączenie co 60 sekund. - *ID klienta:* mqtt-explorer-9ee7f326 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 62069 (losowo wybrany port przypisany do aplikacji MQTT Explorer) - *Port docelowy:* 1883 (port na którym uruchomiony jest serwer mqtt://test.mosquitto.org) - *Numer sekwencyjny:* 1 - *Numer potwierdzenia:* 1 - *Długość danych:* 36 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv4 (Internet Protocol Version 4) - *Adres źródłowy:* 192.168.88.246 (adres IP komputera na którym uruchomiony został MQTT Explorer) - *Adres docelowy:* 91.121.93.94 (adres IP serwera test.mosquitto.org) - **Warstwa L2 (Łącza danych):** - *Adres MAC źródłowy:* e0:3f:49:ac:80:55 (adres MAC komputera na którym uruchomiony został MQTT Explorer) - *Adres MAC docelowy:* c4:ad:34:37:c9:04 (prawdopodobnie adres MAC switcha w sieci lokalnej) <!-- ``` Frame 45440: 90 bytes on wire (720 bits), 90 bytes captured (720 bits) on interface \Device\NPF_{7D37A203-EC54-4B36-9252-3D67678ADEA5}, id 0 Ethernet II, Src: ASUSTekC_ac:80:55 (e0:3f:49:ac:80:55), Dst: Routerbo_37:c9:04 (c4:ad:34:37:c9:04) Internet Protocol Version 4, Src: 192.168.88.246, Dst: 91.121.93.94 Transmission Control Protocol, Src Port: 62069, Dst Port: 1883, Seq: 1, Ack: 1, Len: 36 MQ Telemetry Transport Protocol, Connect Command Header Flags: 0x10, Message Type: Connect Command 0001 .... = Message Type: Connect Command (1) .... 0000 = Reserved: 0 Msg Len: 34 Protocol Name Length: 4 Protocol Name: MQTT Version: MQTT v3.1.1 (4) Connect Flags: 0x02, QoS Level: At most once delivery (Fire and Forget), Clean Session Flag Keep Alive: 60 Client ID Length: 22 Client ID: mqtt-explorer-9ee7f326 ``` --> ### 1.3.2. CONNACK ![image](https://hackmd.io/_uploads/rkT1yXDra.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Connect Ack (Potwierdzenie połączenia) - *Długość wiadomości:* 2 bajty - *Flagi nagłówka:* - *Message Type:* Connect Ack (2) - *Reserved:* 0 - *Długość wiadomości (Msg Len):* 2 - *Flagi potwierdzenia (Acknowledge Flags):* - *Reserved:* Nie ustawione - *Session Present:* Nie ustawione - *Return Code:* Connection Accepted (0) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1883 - *Port docelowy:* 62069 - *Numer sekwencyjny:* 1 - *Numer potwierdzenia:* 37 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv4 (Internet Protocol Version 4) - *Adres źródłowy:* 91.121.93.94 - *Adres docelowy:* 192.168.88.246 <!-- ``` Frame 45443: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface \Device\NPF_{7D37A203-EC54-4B36-9252-3D67678ADEA5}, id 0 Ethernet II, Src: Routerbo_37:c9:04 (c4:ad:34:37:c9:04), Dst: ASUSTekC_ac:80:55 (e0:3f:49:ac:80:55) Internet Protocol Version 4, Src: 91.121.93.94, Dst: 192.168.88.246 Transmission Control Protocol, Src Port: 1883, Dst Port: 62069, Seq: 1, Ack: 37, Len: 4 MQ Telemetry Transport Protocol, Connect Ack Header Flags: 0x20, Message Type: Connect Ack 0010 .... = Message Type: Connect Ack (2) .... 0000 = Reserved: 0 Msg Len: 2 Acknowledge Flags: 0x00 0000 000. = Reserved: Not set .... ...0 = Session Present: Not set Return Code: Connection Accepted (0) ``` --> ### 1.3.3. SUBSCRIBE ![image](https://hackmd.io/_uploads/r1Ol1mwHa.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Subscribe Request (Żądanie subskrypcji) - *Długość wiadomości:* 16 bajtów - *Flagi nagłówka:* - *Message Type:* Subscribe Request (8) - *Reserved:* 2 - *Długość wiadomości (Msg Len):* 14 - *Message Identifier:* 37903 - *Długość tematu (Topic Length):* 9 - *Temat (Topic):* /w2mqqt/+ - *Żądany poziom usługi jakości (Requested QoS):* At most once delivery (Fire and Forget) (0) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 62069 - *Port docelowy:* 1883 - *Numer sekwencyjny:* 37 - *Numer potwierdzenia:* 5 - *Długość danych:* 16 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv4 (Internet Protocol Version 4) - *Adres źródłowy:* 192.168.88.246 - *Adres docelowy:* 91.121.93.94 <!-- ``` Frame 45444: 70 bytes on wire (560 bits), 70 bytes captured (560 bits) on interface \Device\NPF_{7D37A203-EC54-4B36-9252-3D67678ADEA5}, id 0 Ethernet II, Src: ASUSTekC_ac:80:55 (e0:3f:49:ac:80:55), Dst: Routerbo_37:c9:04 (c4:ad:34:37:c9:04) Internet Protocol Version 4, Src: 192.168.88.246, Dst: 91.121.93.94 Transmission Control Protocol, Src Port: 62069, Dst Port: 1883, Seq: 37, Ack: 5, Len: 16 MQ Telemetry Transport Protocol, Subscribe Request Header Flags: 0x82, Message Type: Subscribe Request 1000 .... = Message Type: Subscribe Request (8) .... 0010 = Reserved: 2 Msg Len: 14 Message Identifier: 37903 Topic Length: 9 Topic: /w2mqqt/+ Requested QoS: At most once delivery (Fire and Forget) (0) ``` --> ### 1.3.4. SUBACK ![image](https://hackmd.io/_uploads/BkUbJQvSa.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Subscribe Ack (Potwierdzenie subskrypcji) - *Długość wiadomości:* 5 bajtów - *Flagi nagłówka:* - *Message Type:* Subscribe Ack (9) - *Reserved:* 0 - *Długość wiadomości (Msg Len):* 3 - *Message Identifier:* 37903 - *Przyznany poziom usługi jakości (Granted QoS):* At most once delivery (Fire and Forget) (0) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1883 - *Port docelowy:* 62069 - *Numer sekwencyjny:* 5 - *Numer potwierdzenia:* 53 - *Długość danych:* 5 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv4 (Internet Protocol Version 4) - *Adres źródłowy:* 91.121.93.94 - *Adres docelowy:* 192.168.88.246 <!-- ``` Frame 45446: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface \Device\NPF_{7D37A203-EC54-4B36-9252-3D67678ADEA5}, id 0 Ethernet II, Src: Routerbo_37:c9:04 (c4:ad:34:37:c9:04), Dst: ASUSTekC_ac:80:55 (e0:3f:49:ac:80:55) Internet Protocol Version 4, Src: 91.121.93.94, Dst: 192.168.88.246 Transmission Control Protocol, Src Port: 1883, Dst Port: 62069, Seq: 5, Ack: 53, Len: 5 MQ Telemetry Transport Protocol, Subscribe Ack Header Flags: 0x90, Message Type: Subscribe Ack 1001 .... = Message Type: Subscribe Ack (9) .... 0000 = Reserved: 0 Msg Len: 3 Message Identifier: 37903 Granted QoS: At most once delivery (Fire and Forget) (0) ``` --> ### 1.3.5. DISCONNECT ![image](https://hackmd.io/_uploads/rygmyXPBa.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Disconnect Request (Żądanie rozłączenia) - *Długość wiadomości:* 2 bajty - *Flagi nagłówka:* - *Message Type:* Disconnect Request (14) - *Reserved:* 0 - *Długość wiadomości (Msg Len):* 0 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 62069 - *Port docelowy:* 1883 - *Numer sekwencyjny:* 53 - *Numer potwierdzenia:* 10 - *Długość danych:* 2 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv4 (Internet Protocol Version 4) - *Adres źródłowy:* 192.168.88.246 - *Adres docelowy:* 91.121.93.94 <!-- ``` Frame 45510: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_{7D37A203-EC54-4B36-9252-3D67678ADEA5}, id 0 Ethernet II, Src: ASUSTekC_ac:80:55 (e0:3f:49:ac:80:55), Dst: Routerbo_37:c9:04 (c4:ad:34:37:c9:04) Internet Protocol Version 4, Src: 192.168.88.246, Dst: 91.121.93.94 Transmission Control Protocol, Src Port: 62069, Dst Port: 1883, Seq: 53, Ack: 10, Len: 2 MQ Telemetry Transport Protocol, Disconnect Req Header Flags: 0xe0, Message Type: Disconnect Req 1110 .... = Message Type: Disconnect Req (14) .... 0000 = Reserved: 0 Msg Len: 0 ``` --> --- # Ćwiczenie 2 ## 2.1. Uruchom własny broker mosquitto: `mosquitto.exe -v -p 1883` ![image](https://hackmd.io/_uploads/BJiZG7vHp.png) ## 2.2. W programie Wireshark włącz przechwytywanie na lokalnym interfejsie sieciowym ![image](https://hackmd.io/_uploads/S1mrGXDHT.png) ## 2.3. Uruchomienie klienta subskrybującego temat „mosiot": `mosquitto_sub -v -h localhost -t "mosiot"` ![image](https://hackmd.io/_uploads/By8VMmPBT.png) ## 2.4. Uruchomienie klienta publikującego w temacie „mosiot": `mosquitto_pub -h localhost -t "mosiot" -m "Testowa wiadomosc"` ![image](https://hackmd.io/_uploads/HJrXmXwr6.png) ## 2.5. Umieść w protokole zrzuty z Wiresharka pokazujące dane pakiety, dokładnie zinterpretuj je dla warstw warstw L3, L4 i L7 <!-- Opisał bym tu przepływ wiadomości, ale brakuje mi drugiego publisha - jest z publishera do brokera ale nie widać z brokera do subscribera. Można napisać że może nie dotarł do brokera i dlatego broker nie dał do subscribera --> Na poniższym zrzucie ekranu przedstawione są różne rodzaje pakietów przesyłanych w ramach komunikacji MQTT: 1. **Connect oraz Subscribe Request:** - Pakiety inicjalizacyjne ustanawiające połączenie oraz zgłaszające subskrypcję do tematu "mosito". 2. **Ping Request - Podtrzymanie połączenia:** - Pakiet wysyłany okresowo w celu utrzymania aktywności połączenia. 3. **Ponowny Connect oraz Subscribe Request:** - Po zrestartowaniu przez nas klienta mosquitto_sub, wysyłane zostały ponownie pakiety połączenia i subskrypcji. 4. **Ping Request - Podtrzymanie połączenia:** - Kolejny pakiet ping, mający na celu utrzymanie stałego połączenia. 5. **Connect oraz Publish - Uruchomienie klienta mosquitto_pub, opublikowanie wiadomości "Testowa wiadomość":** - Żądanie połączenia i opublikowanie wiadomości do tematu "mossito" przez klienta mosquitto_pub. 6. **Ping Request - Podtrzymanie połączenia:** - Kolejny pakiet ping, dbający o utrzymanie stałego połączenia. ![image](https://hackmd.io/_uploads/B1j9-gcHa.png) Widoczny jest brak pakietu publish wysłanego przez brokera MQTT do klienta, który zasubskrybował temat "mosito". Nie jesteśmy pewni, z czego wynika brak tego pakietu, możliwe przyczyny obejmują: 1. Problem z Połączeniem 2. Błąd w Subskrypcji Klienta 3. Niepoprawna Konfiguracja Tematu 4. Brak Publikacji na Brokerze 5. Błędy w Logice Aplikacji ### 2.5.1. SUBSCRIBE ![image](https://hackmd.io/_uploads/SJt2fmvBp.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Subscribe Request (Żądanie subskrypcji) - *Długość wiadomości:* 13 bajtów - *Flagi nagłówka:* - *Message Type:* Subscribe Request - *Reserved:* 2 - *Długość wiadomości (Msg Len):* 11 - *Message Identifier:* 1 - *Długość tematu (Topic Length):* 6 - *Temat (Topic):* mosiot - *Żądany poziom usługi jakości (Requested QoS):* At most once delivery (Fire and Forget) (0) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 62244 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 15 - *Numer potwierdzenia:* 5 - *Długość danych:* 13 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) - **Warstwa L2 (Łącza danych):** - *Typ:* Null/Loopback (localhost - adres serwera i klienta mqtt) <!-- ``` Frame 2267: 77 bytes on wire (616 bits), 77 bytes captured (616 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 6, Src: ::1, Dst: ::1 Transmission Control Protocol, Src Port: 62244, Dst Port: 1817, Seq: 15, Ack: 5, Len: 13 MQ Telemetry Transport Protocol, Subscribe Request Header Flags: 0x82, Message Type: Subscribe Request Msg Len: 11 Message Identifier: 1 Topic Length: 6 Topic: mosiot Requested QoS: At most once delivery (Fire and Forget) (0) ``` --> ### 2.5.2. SUBACK ![image](https://hackmd.io/_uploads/r18TzQPST.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Subscribe Ack (Potwierdzenie subskrypcji) - *Długość wiadomości:* 5 bajtów - *Flagi nagłówka:* - *Message Type:* Subscribe Ack - *Reserved:* 0 - *Długość wiadomości (Msg Len):* 3 - *Message Identifier:* 1 - *Przyznany poziom usługi jakości (Granted QoS):* At most once delivery (Fire and Forget) (0) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 - *Port docelowy:* 62244 - *Numer sekwencyjny:* 5 - *Numer potwierdzenia:* 28 - *Długość danych:* 5 bajtów <!-- ``` Frame 2269: 69 bytes on wire (552 bits), 69 bytes captured (552 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 6, Src: ::1, Dst: ::1 Transmission Control Protocol, Src Port: 1817, Dst Port: 62244, Seq: 5, Ack: 28, Len: 5 MQ Telemetry Transport Protocol, Subscribe Ack Header Flags: 0x90, Message Type: Subscribe Ack Msg Len: 3 Message Identifier: 1 Granted QoS: At most once delivery (Fire and Forget) (0) ``` --> ### 2.5.3. PUBLISH ![image](https://hackmd.io/_uploads/ry-AfXPBp.png) - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Message (Publikacja wiadomości) - *Długość wiadomości:* 27 bajtów - *Flagi nagłówka:* - *Message Type:* Publish Message - *QoS Level:* At most once delivery (Fire and Forget) - *Długość wiadomości (Msg Len):* 25 - *Długość tematu (Topic Length):* 6 - *Temat (Topic):* mosito - *Wiadomość (Message):* 546573746f776120776961646f6d6f7363 (heksadecymalny zapis ASCII: "Testowa wiadomość") - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 62262 - *Port docelowy:* 1817 - *Numer sekwencyjny:* 15 - *Numer potwierdzenia:* 5 - *Długość danych:* 27 bajtów <!-- ``` Frame 4019: 91 bytes on wire (728 bits), 91 bytes captured (728 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 6, Src: ::1, Dst: ::1 Transmission Control Protocol, Src Port: 62262, Dst Port: 1817, Seq: 15, Ack: 5, Len: 27 MQ Telemetry Transport Protocol, Publish Message Header Flags: 0x30, Message Type: Publish Message, QoS Level: At most once delivery (Fire and Forget) Msg Len: 25 Topic Length: 6 Topic: mosito Message: 546573746f776120776961646f6d6f7363 ``` --> --- # Ćwiczenie 3 Architektura zadania: - własny broker mosquitto - wireshark (na brokerze) - klient mosquito_pub - klient mosquito_sub ## 3.1. Uruchom w odrębnych konsolach i obserwuj rezultaty dla różnych QoS. `Subskrybent, np: mosquitto_sub -d -v -q 2 -h localhost -t "iot"` `Wydawca, np: mosquitto_pub -d -q 1 -h localhost -t "iot" -m "tekst"` Podane polecenia uruchomiliśmy w terminalach i przeszliśmy do kolejnych poleceń. ## 3.2. Umieść w protokole zrzuty z Wiresharka pokazujące PUBLISH i PUBACK/PUBREC, PUBREL i PUBCOMP. Dokładnie zinterpretuj te pakiety dla warstw L3, L4 i L7. Należy przedstawić komunikację w kanałach PUB-Broker i Broker-SUB dla różnych przypadków QoS: PCAP: https://we.tl/t-Q4lM9InzVg - ściagnięte na lapku pracowym w `Desktop/Studia/W2` Kolejność: 2,1,3 (zadania) ### 3.2.1. P-B i B-S QoS1 Modelowy przebieg w QoS1 pokazany na wykładzie: ![obraz](https://hackmd.io/_uploads/Sy0l3B9HT.png) Ponieważ tutaj zarówno P-B jak i B-S mają QoS1, to przebieg ten można by zmodyfikować w następujący sposób: ![obraz](https://hackmd.io/_uploads/Sy10fL9HT.png) Dokładnie taki przebieg można zaobserwować na zebranym zrzucie pcap: Przebieg uchwycony w trakcie eksperymentów: ![obraz](https://hackmd.io/_uploads/BkKk4IqBp.png) Poniżej zamieszczamy dokładną analizę tych czterech pakietów **Pakiet 2 - Publish**: - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Message - *Długość wiadomości:* 12 bajtów - *Długość tematu (Topic Length):* 3 - *Temat (Topic):* iot - *Żądany poziom usługi jakości (Requested QoS):* At least once delivery (Acknowledged deliver) - *Treść wiadomości (Message):* "74656b7374" (czytane jako "tekst" w kodzie ASCII) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53982 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 15 - *Numer potwierdzenia:* 5 - *Długość danych:* 14 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 4 - Publish**: - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Message - *Długość wiadomości:* 12 bajtów - *Długość tematu (Topic Length):* 3 - *Temat (Topic):* iot - *Żądany poziom usługi jakości (Requested QoS):* At least once delivery (Acknowledged deliver) - *Treść wiadomości (Message):* "74656b7374" (czytane jako "tekst" w kodzie ASCII) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53979 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 10 - *Numer potwierdzenia:* 25 - *Długość danych:* 14 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 5** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Ack - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53979 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 25 - *Numer potwierdzenia:* 24 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 7** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Ack - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53982 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 5 - *Numer potwierdzenia:* 29 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) ### 3.2.2. P-B i B-S QoS2 Modelowy przebieg QoS2 dla obu stron: ![obraz](https://hackmd.io/_uploads/HkPP_RlLp.png) Zmapowanie modelu na faktyczny zaobserwowany przebieg: ![obraz](https://hackmd.io/_uploads/H1ffYAxUa.png) Poniżej zamieszczamy dokładną analizę tych pakietów: **Pakiet 2** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Message - *Długość wiadomości:* 12 bajtów - *Długość tematu (Topic Length):* 3 - *Temat (Topic):* iot - *Poziom usługi jakości (QoS Level):* Exactly once delivery (Assured Delivery) - *Treść wiadomości (Message):* "74656b7374" (czytane jako "tekst" w kodzie ASCII) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53957 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 15 - *Numer potwierdzenia:* 5 - *Długość danych:* 14 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 8** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Received - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53957 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 5 - *Numer potwierdzenia:* 29 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 9** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Release - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53957 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 29 - *Numer potwierdzenia:* 9 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 4** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Message - *Długość wiadomości:* 12 bajtów - *Długość tematu (Topic Length):* 3 - *Temat (Topic):* iot - *Poziom usługi jakości (QoS Level):* Exactly once delivery (Assured Delivery) - *Treść wiadomości (Message):* "74656b7374" (czytane jako "tekst" w kodzie ASCII) - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53937 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 12 - *Numer potwierdzenia:* 27 - *Długość danych:* 14 bajtów - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 5** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Received - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53937 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 27 - *Numer potwierdzenia:* 26 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 11** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Complete - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53957 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 9 - *Numer potwierdzenia:* 33 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 6** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Release - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 1817 (port wystawionego serwera mqtt) - *Port docelowy:* 53937 (port wystawionego klienta mqtt) - *Numer sekwencyjny:* 26 - *Numer potwierdzenia:* 31 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) **Pakiet 7** - **Warstwa L7 (Aplikacyjna):** - *Protokół:* MQTT (Message Queuing Telemetry Transport) - *Typ wiadomości:* Publish Complete - *Długość wiadomości:* 2 bajty - *Identyfikator wiadomości (Message Identifier):* 1 - **Warstwa L4 (Transportowa):** - *Protokół:* TCP (Transmission Control Protocol) - *Port źródłowy:* 53937 (port wystawionego klienta mqtt) - *Port docelowy:* 1817 (port wystawionego serwera mqtt) - *Numer sekwencyjny:* 31 - *Numer potwierdzenia:* 30 - *Długość danych:* 4 bajty - **Warstwa L3 (Sieciowa):** - *Protokół:* IPv6 (Internet Protocol Version 6) - *Adres źródłowy:* ::1 (localhost - adres serwera i klienta mqtt) - *Adres docelowy:* ::1 (localhost - adres serwera i klienta mqtt) ### 3.2.3. P-B QoS2 i B-S QoS1 Modelowy przebieg takiej sytuacji: ![obraz](https://hackmd.io/_uploads/rJYM2AgU6.png) Mapowanie na zaobserwowaną sytuajcję: ![obraz](https://hackmd.io/_uploads/B1NTn0gUa.png) Wszystkie typy pakietów, które ozstały tu użyte, już bardzo dokładnie opisaliśmy przy oakzji poprzednich przypadków dlatego już nie będziemy się powtarzać. --- # Ćwiczenie 4 ## 4.1. Zainstaluj OpenSSL, umieść plik openssl.cnf w lokalizacji `C:\OpenSSL\SSL`(wersja portable: https://sourceforge.net/projects/openssl-for-windows/) ![image](https://hackmd.io/_uploads/S18HI7Drp.png) ## 4.2. Utwórz klucz prywatny, np.: openssl genrsa -out mqttclient.key ![image](https://hackmd.io/_uploads/ByaDL7vH6.png) ## 4.3. Utwórz żądanie certyfikatu (wszystkie pola żądania muszą być zdefiniowane), np.: `openssl req -out mqttclient.csr -key mqttclient.key –new` ![image](https://hackmd.io/_uploads/HylrPXDrp.png) ## 4.4. Wyślij żądanie certyfikatu klienta przez formularz na stronie (używając danych w pliku .csr): https://test.mosquitto.org/ssl/index.php ![image](https://hackmd.io/_uploads/B1YiwQDBp.png) ## 4.5. Zapisz pobrany certyfikat klienta w znanej lokalizacji ![image](https://hackmd.io/_uploads/BywkdmPB6.png) ## 4.6. Pobierz certyfikat brokera i zapisz go w znanej lokalizacji ![image](https://hackmd.io/_uploads/HkKz_XPrp.png) ## 4.7. Skonfiguruj MQTT Explorer do połączeń szyfrowanych z brokerem `mqtt://test.mosquitto.org` ![image](https://hackmd.io/_uploads/HkIl57vBT.png) ![image](https://hackmd.io/_uploads/BJSZ9mvST.png) --- ## 4.8. W programie Wireshark włącz przechwytywanie na właściwym interfejsie sieciowym ![image](https://hackmd.io/_uploads/Bk8hcXwrp.png) ## 4.9. Korzystając z aplikacji okienkowej np. MQTT Explorer: ### 4.9.1. Ustaw nasłuchiwanie komunikatów w tematach (QoS 2) `/w2mqqts/+` ![image](https://hackmd.io/_uploads/B1ScqXvra.png) ### 4.9.2. Nadaj kilka przykładowych komunikatów w temacie odpowiadającym numerowi Twojego zespołu, `(zespol_003)` ![image](https://hackmd.io/_uploads/B1lyaQDHT.png) ## 4.10 Rozłącz klienta MQTT ![image](https://hackmd.io/_uploads/Skb8pXPBa.png) ## 4.11 Umieść w protokole zrzuty z Wiresharka i dokonaj analizy obserwowanych pakietów ![image](https://hackmd.io/_uploads/B1lZhScHa.png) Podczas analizy pakietów za pomocą Wiresharka zarejestrowano następujące kluczowe zdarzenia w komunikacji: 1. **Nawiązanie Połączenia TCP - Włączenie Klienta i Podłączenie do Serwera:** - Zarejestrowane są pakiety inicjalizujące nawiązywanie połączenia TCP, co odpowiada włączeniu klienta oraz jego pomyślnemu połączeniu z serwerem MQTT. 2. **Zestawienie Szyfrowania TLS - Klient - Serwer:** - W trakcie komunikacji obserwuje się pakiety związane z zestawianiem protokołu TLS, co wskazuje na proces ustanawiania bezpiecznego połączenia pomiędzy klientem a serwerem MQTT. Wymienione zostają wiadomości `Client hello` oraz `Server hello` 3. **Wymiana Zaszyfrowanych Danych - Publikowanie Wiadomości przez Klienta:** - Zauważalne są pakiety z wymianą zaszyfrowanych danych, odpowiadają one za przesłanie publikowanych wiadomości przez klienta do brokera MQTT. Zidentyfikowane zostają odpowiednie ramki zawierające dane zaszyfrowane protokołem TLS. 4. **Zakończenie Połączenia - Rozłączenie Klienta MQTT:** - Zarejestrowane są pakiety związane z zakończeniem połączenia TCP, co odpowiada rozłączaniu klienta MQTT. Ten etap obejmuje proces kończenia sesji komunikacyjnej między klientem a brokerem MQTT. #### 4.11.1 Pakiet Client hello ![image](https://hackmd.io/_uploads/SkWEnB5Ba.png) Poniżej przedstawiam analizę najważniejszych elementów pakietu Client hello: - **Internet Protocol Version 4:** - Adres źródłowy IP: 192.168.88.246 - Adres docelowy IP: 91.121.93.94 - **Transmission Control Protocol (TCP):** - Port źródłowy: 59522 - Port docelowy: 8883 - Numer sekwencji: 1 - Numer potwierdzenia: 1 - **Transport Layer Security (TLS):** - Wersja TLS: 1.3 - Warstwa rekordu TLS zawiera protokół Handshake. - **Handshake Protocol: Client Hello:** - Wersja TLS: 1.2 - Identyfikator losowy (Random) - ID sesji (Session ID) - Długość zestawu szyfrów (Cipher Suites Length): 36 - Zestaw szyfrów (Cipher Suites): Wskazuje preferowane algorytmy szyfrowania, takie jak AES-128-GCM-SHA256, AES-256-GCM-SHA384, itp. - Długość metod kompresji (Compression Methods Length): 1 - Metody kompresji (Compression Methods): Wskazuje używane metody kompresji. - Rozszerzenia: Server Name, Extended Master, Renegotiation Info, Supported Groups, EC Point Formats, Session Ticket, Signature Algorithms, Key Share, PSK Key Exchange Modes, Supported Versions - **JA3 (Client Fingerprint):** - JA3 Fullstring: 771,4865-4866-4867-49199-49195-49200-49196-52393-52392-49161-49171-49162-49172-156-157-47-53-10,0-23-65281-10-11-35-13-51-45-43,29-23-24,0 - JA3: dda262729e5413660ec0e6a8d4279860 Analiza tego pakietu wskazuje na inicjalizację połączenia TLS pomiędzy klientem a serwerem. Różnorodność zestawu szyfrów, obsługiwanych rozszerzeń i identyfikatorów pozwalają na zrozumienie negocjowanych parametrów bezpieczeństwa i charakterystyki klienta. #### 4.11.2 Pakiet Server hello ![image](https://hackmd.io/_uploads/rJpU3B5ra.png) Poniżej znajduje się analiza najważniejszych elementów pakietu Server hello: - **Internet Protocol Version 4:** - Adres źródłowy IP: 91.121.93.94 - Adres docelowy IP: 192.168.88.246 - **Transmission Control Protocol (TCP):** - Port źródłowy: 8883 - Port docelowy: 59522 - Numer sekwencji: 1 - Numer potwierdzenia: 258 - **Transport Layer Security (TLS):** - Wersja TLS: 1.2 - Warstwa rekordu TLS zawiera protokół Handshake. - **Handshake Protocol: Server Hello:** - Wersja TLS: 1.2 - Identyfikator losowy (Random) - ID sesji (Session ID) - Zestaw szyfrów (Cipher Suite): TLS_AES_256_GCM_SHA384 - Metoda kompresji: null (brak kompresji) - Rozszerzenia (Extensions): Supported Versions, Key Share - **JA3S (Server Fingerprint):** - JA3S Fullstring: 771,4866,43-51 - JA3S: 15af977ce25de452b96affa2addb1036 - **Change Cipher Spec Protocol: Change Cipher Spec:** - Potwierdzenie zmiany specyfikacji szyfrowania. - **Application Data Protocol: MQTT:** - Wysłane dane aplikacyjne protokołu MQTT. Analiza tego pakietu wskazuje, że serwer MQTT odpowiedział protokołem TLS 1.2 na Client Hello od klienta. Server Hello zawiera informacje o zastosowanym szyfrowaniu, a rozszerzenia wskazują na obsługiwane wersje i klucze sesji. Następnie protokół zmienia specyfikację szyfrowania, co oznacza rozpoczęcie bezpiecznej komunikacji, a dane aplikacyjne protokołu MQTT są przesyłane. #### 4.11.3 Pakiet z zaszyfrowanymi danymi protokołu mqtt ![image](https://hackmd.io/_uploads/BJbdM85Bp.png) Poniżej znajduje się analiza najważniejszych elementów zaszywrowanego pakietu przenoszącego ramki protokołu MQTT: - **Internet Protocol Version 4:** - Adres źródłowy IP: 192.168.88.246 - Adres docelowy IP: 91.121.93.94 - **Transmission Control Protocol (TCP):** - Port źródłowy: 59522 - Port docelowy: 8883 - Numer sekwencji: 396 - Numer potwierdzenia: 1668 - **Transport Layer Security (TLS):** - Wersja TLS: 1.2 - Warstwa rekordu TLS zawiera dane aplikacyjne protokołu MQTT. - **Application Data Protocol: MQTT:** - Opaque Type: Application Data (23) - Długość: 34 - Zaszyfrowane dane aplikacyjne protokołu MQTT. Analiza tego pakietu wskazuje, że zawiera on zaszyfrowane dane aplikacyjne protokołu MQTT. Długość pakietu wynosi 34 bajty, a protokół TLS w wersji 1.2 został użyty do zabezpieczenia komunikacji między klientem a serwerem. Odczytanie konkretnych danych wymagałoby odszyfrowania tych zaszyfrowanych danych, co jest zazwyczaj możliwe tylko przy użyciu klucza prywatnego. <!-- https://we.tl/t-EAs0KZ2r55 - ściagnięte na lapku pracowym w `Desktop/Studia/W2` -->

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully