ネットワークのことを知るため ソフトウェアルータを 自作した話

A96a5f977a4d024000d82e590554f847?s=47 kobatako
March 31, 2019

ネットワークのことを知るため ソフトウェアルータを 自作した話

A96a5f977a4d024000d82e590554f847?s=128

kobatako

March 31, 2019
Tweet

Transcript

  1. ωοτϫʔΫͷ͜ͱΛ஌ΔͨΊ ιϑτ΢ΣΞϧʔλΛ ࣗ࡞ͨ͠࿩ PHPerKaigi 2019 2019/3/30ʢ౔ʣ খݪਸ׮

  2. ࣗݾ঺հ • ໊લ : খݪ ਸ׮ʢ͜͹Δ ͔ͨͻΖʣ • ॴଐ :

    גࣜձࣾFusic • ࢓ࣄ : PHPɺGolangɺAWS • झຯ : ElixirɺErlangɺΠϯϑϥ͍Ζ͍Ζ • Twitter : kobatako_
  3. ͸͡ΊʹͰ͕͢ɾɾɾ

  4. ωοτϫʔΫҙࣝͯ͠ ·͔͢ʁ

  5. ωοτϫʔΫ޷͖Ͱ͔͢ʁ

  6. ωοτϫʔΫେ޷͖ Ͱ͢ΑͶʁ

  7. ͦΜͳΈΜͳେ޷͖ ωοτϫʔΫʹؔ͢Δ ࿩Λ͠·͢

  8. ΞδΣϯμ • ωοτϫʔΫͱϧʔλͷؔ܎ • ϧʔλͷ࣮૷ʢErlangʣ • Ϟδϡʔϧͷ࣮૷ʢElixirʣ • ·ͱΊ

  9. ωοτϫʔΫͱϧʔλͷ ؔ܎

  10. Λཧղ͢ΔͨΊʹϧʔλ͕ԿΛ
 ΍͍ͬͯΔͷ͔

  11. σʔλʢύέοτʣΛ̎ͭҎ্ͷҟͳΔ ωοτϫʔΫؒΛதܧɺ ͦͷͨΊͷૹ৴ઌΛ൑அͯ͘͠ΕΔ

  12. σʔλʢύέοτʣΛ̎ͭҎ্ͷҟͳΔ ωοτϫʔΫؒΛதܧɺ ͦͷͨΊͷૹ৴ઌΛ൑அͯ͘͠ΕΔ

  13. ϧʔλ͸ωοτϫʔΫؒΛͭͳ͙

  14. ૹ৴ઌΛ൑அ = ϧʔςΟϯά

  15. ϧʔςΟϯάΛཧղ͢Ε͹ ϧʔλͷ͜ͱ͕Θ͔Γ ωοτϫʔΫͷ͜ͱ΋ ෼͔ͬͯ͘ΔͷͰ͸ɾɾɾ

  16. ϧʔςΟϯάͱ͸

  17. ϧʔςΟϯά • ύέοτΛૹ৴ઌͱͳΔϗετʹసૹ͢ΔͨΊ ࠷దͳܦ࿏Λબ୒͢Δ • IPΞυϨεΛར༻

  18. ϧʔςΟϯάʹؔ͢Δ΋ͷ • ϧʔςΟϯάςʔϒϧ • ϧʔτ৘ใ͕อଘ͞Ε͍ͯΔςʔϒϧ • ελςΟοΫϧʔςΟϯά • ؅ཧऀ͕௚઀ઃఆͨ͠ϧʔτ৘ใ •

    μΠφϛοΫϧʔςΟϯά • ϧʔςΟϯάϓϩτίϧ͔Βऔಘͨ͠ϧʔτ৘ใ
  19. ϧʔςΟϯάʹؔ͢Δ΋ͷ • ϧʔςΟϯάςʔϒϧͷྫ ৘ใݯ Ѽઌϧʔτ αϒωοτϚεΫ AD ϝτϦοΫ ωΫετϗοϓ ग़ྗIF

    C 192.168.0.0 255.255.255.0 0 0 - Eth0 C 192.168.10.0 255.255.255.0 0 0 - Eth1 S 192.168.30.0 255.255.255.0 1 0 192.168.10.1 Eth1 R 192.168.40.0 255.255.255.0 120 1 192.168.0.1 Eth0 R 192.168.40.0 255.255.255.0 120 4 192.168.10.1 Eth1
  20. ϧʔλͷ࣮૷ ʢErlangʣ

  21. ࣮૷ͨ͠಺༰ʹ͍ͭͯ

  22. ॲཧϑϩʔ ύέοτͷड৴ -͕*1͔֬ೝ νΣοΫαϜͷ֬ೝ 55-Λ 55-͕͔Ͳ͏͔֬ೝ νΣοΫαϜͷ࠶ܭࢉ ωΫετϗοϓͷ."$ ΞυϨεͷऔಘ -ͷϔομʔΛ࡞੒

    ύέοτΛૹ৴ -ͷॲཧ ※ϧʔςΟϯάॲཧΛ૝ఆ ϧʔςΟϯάςʔϒϧ ͔Βϧʔτ৘ใΛऔಘ
  23. ॲཧϑϩʔ ύέοτͷड৴ -͕*1͔֬ೝ νΣοΫαϜͷ֬ೝ 55-Λ 55-͕͔Ͳ͏͔֬ೝ νΣοΫαϜͷ࠶ܭࢉ ωΫετϗοϓͷ."$ ΞυϨεͷऔಘ -ͷϔομʔΛ࡞੒

    ύέοτΛૹ৴ -ͷॲཧ ※ϧʔςΟϯάॲཧΛ૝ఆ ϧʔςΟϯάςʔϒϧ ͔Βϧʔτ৘ใΛऔಘ
  24. ͲͷΑ͏ʹͯ͠ ϧʔςΟϯάςʔϒϧ͔Β ϧʔτ৘ใΛऔಘ͢Δͷ͔

  25. ܾΊΔͱ͖ͷ༏ઌॱ 1. ϩϯήετϚον ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτͰ࠷΋௕͘ Ϛον͢Δϧʔτ৘ใ 2. ADʢΞυϛχετϨʔςΟϒσΟελϯεʣ ৘ใݯͷ৴པੑ 3. ϝτϦοΫ

    ࠷దܦ࿏Λબ୒͢ΔͨΊʹ࢖༻͞ΕΔ஋
  26. ܾΊΔͱ͖ͷ༏ઌॱ • ϩϯήετϚονͷྫ • ૹ৴ઌ͕192.168.10.1ʹରͯ͠ϧʔςΟϯάςʔϒϧ͕
 Լهͷ৔߹ • ѼઌωοτϫʔΫ : 192.168.0.0/16

    • ѼઌωοτϫʔΫ : 192.168.10.0/24 
 -> 192.168.10.0ͷѼઌϧʔτΛ࣋ͭϧʔτ৘ใ͕
 ࢀর͞ΕΔ ৘ใݯ Ѽઌϧʔτ αϒωοτϚεΫ AD ϝτϦοΫ ωΫετϗοϓ ग़ྗIF S 192.168.0.0 255.255.0.0 1 0 192.168.0.1 Eth0 R 192.168.10.0 255.255.255.0 120 0 192.168.10.1 Eth1
  27. ܾΊΔͱ͖ͷ༏ઌॱ • ΞυϛχετϨʔςΟϒσΟελϯεʢADʣ • ৘ใݯͷ৴༻౓ • ADͷ஋͕௿͍΋ͷ͕༏ઌ͞ΕΔ

  28. ܾΊΔͱ͖ͷ༏ઌॱ • ྫɿCiscoػثʹ͓͚ΔσϑΥϧτͷAD஋ ߴ ௿ ৘ใݯ σϑΥϧτͷAD஋ ઀ଓ͞Ε͍ͯΔΠϯλʔϑΣΠε 0 ελςΟοΫϧʔςΟϯά

    1 αϚϦʔϧʔτ 5 ֎෦BGP 20 IGRP 100 OSPF 110 RIP 120 EGP 140 ಺෦BGP 200 ෆ໌ 255
  29. ܾΊΔͱ͖ͷ༏ઌॱ • ϝτϦοΫ • ҰͭͷϧʔςΟϯάϓϩτίϧͰෳ਺ܦ࿏Λ࣋ͭ৔߹ɺͦΕͧΕͷ
 ܦ࿏͝ͱͷ༏ઌ౓ • খ͍͞ํ͕༏ઌ͞ΕΔ • ϧʔςΟϯάϓϩίτϧ͝ͱʹϝτϦοΫͷѻ͍ํ͕มΘͬͯ͘Δ

    • RIP : ϗοϓ਺ • OSPF : ίετ
  30. ৘ใݯ Ѽઌϧʔτ αϒωοτϚεΫ AD ϝτϦοΫ ωΫετϗοϓ ग़ྗIF C 192.168.0.0 255.255.255.0

    0 0 - Eth0 C 192.168.10.0 255.255.255.0 0 0 - Eth1 S 192.168.30.0 255.255.255.0 1 0 192.168.10.1 Eth1 R 192.168.40.0 255.255.255.0 120 1 192.168.0.1 Eth0 R 192.168.40.0 255.255.255.0 120 4 192.168.10.1 Eth1 ܾΊΔͱ͖ͷ༏ઌॱ 1. ϩϯήετϚον
  31. ৘ใݯ Ѽઌϧʔτ αϒωοτϚεΫ AD ϝτϦοΫ ωΫετϗοϓ ग़ྗIF C 192.168.0.0 255.255.255.0

    0 0 - Eth0 C 192.168.10.0 255.255.255.0 0 0 - Eth1 S 192.168.30.0 255.255.255.0 1 0 192.168.10.1 Eth1 R 192.168.40.0 255.255.255.0 120 1 192.168.0.1 Eth0 R 192.168.40.0 255.255.255.0 120 4 192.168.10.1 Eth1 ܾΊΔͱ͖ͷ༏ઌॱ 2. AD஋Λൺֱ
  32. ৘ใݯ Ѽઌϧʔτ αϒωοτϚεΫ AD ϝτϦοΫ ωΫετϗοϓ ग़ྗIF C 192.168.0.0 255.255.255.0

    0 0 - Eth0 C 192.168.10.0 255.255.255.0 0 0 - Eth1 S 192.168.30.0 255.255.255.0 1 0 192.168.10.1 Eth1 R 192.168.40.0 255.255.255.0 120 1 192.168.0.1 Eth0 R 192.168.40.0 255.255.255.0 120 4 192.168.10.1 Eth1 ܾΊΔͱ͖ͷ༏ઌॱ 3. ϝτϦοΫͷൺֱ
  33. ErlangͰͷ࣮૷

  34. ϧʔςΟϯάॲཧ 2. 1Ͱऔಘͨ͠ϧʔτ৘ใ͔ΒҰ൪༏ઌ౓ͷߴ͍
 ϧʔτ৘ใΛऔಘ 1. ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ Ϛον͢ΔϦετΛऔಘ 3. 2Ͱऔಘͨ͠ϧʔτ৘ใͷωΫετϗοϓ
 ʹૹ৴͢Δ

  35. ϧʔςΟϯάॲཧ 2. 1Ͱऔಘͨ͠ϧʔτ৘ใ͔ΒҰ൪༏ઌ౓ͷߴ͍
 ϧʔτ৘ใΛऔಘ 1. ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ Ϛον͢ΔϦετΛऔಘ 3. 2Ͱऔಘͨ͠ϧʔτ৘ใͷωΫετϗοϓ
 ʹૹ৴͢Δ

  36. ϧʔςΟϯάॲཧ • ྫɿύέοτͷૹ৴ઌ͕192.168.10.1ͷ৔߹ʹ
 ɹɹ౰ͯ͸·Δϧʔτ৘ใ Ѽઌϧʔτ αϒωοτϚεΫ ݁Ռ 192.168.0.0 255.255.0.0 ౰ͯ͸·Δ

    192.168.10.0 255.255.255.0 ౰ͯ͸·Δ 192.168.20.0 255.255.255.0 ౰ͯ͸·Βͳ͍
  37. ϧʔςΟϯάॲཧ ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ ౰ͯ͸·ͬͯΔ΋ͷͷϦετΛऔಘ % ୈҰҾ਺ : ϧʔςΟϯάςʔϒϧ಺ͷશϦετʢarrayʣ % ୈೋҾ਺ :

    ѼઌͷIPʢintegerʣ % ୈࡾҾ਺ : ૹ৴ઌީิʢѼઌͱ൑அ͞Εͨʣͷϧʔτ৘ใʢarrayʣ match_dest_ip([], _, List) -> List; match_dest_ip([{_, _, _, Ip, _, Subnetmask, Ad, Metric, Nexthop, _, If}| Tail], DestIp, List) when is_integer(DestIp) -> case DestIp band Subnetmask of Ip -> match_dest_ip(Tail, DestIp, [{If, Nexthop, Subnetmask, Ad, Metric}|List]); _ -> match_dest_ip(Tail, DestIp, List) end.
  38. ϧʔςΟϯάॲཧ % ୈҰҾ਺ : ϧʔςΟϯάςʔϒϧ಺ͷશϦετʢarrayʣ % ୈೋҾ਺ : ѼઌͷIPʢintegerʣ %

    ୈࡾҾ਺ : ૹ৴ઌީิʢѼઌͱ൑அ͞Εͨʣͷϧʔτ৘ใʢarrayʣ match_dest_ip([], _, List) -> List; match_dest_ip([{_, _, _, Ip, _, Subnetmask, Ad, Metric, Nexthop, _, If}| Tail], DestIp, List) when is_integer(DestIp) -> case DestIp band Subnetmask of Ip -> match_dest_ip(Tail, DestIp, [{If, Nexthop, Subnetmask, Ad, Metric}|List]); _ -> match_dest_ip(Tail, DestIp, List) end. 1. ѼઌIPͱαϒωοτϚεΫͷandॲཧ ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ ౰ͯ͸·ͬͯΔ΋ͷͷϦετΛऔಘ
  39. ϧʔςΟϯάॲཧ % ୈҰҾ਺ : ϧʔςΟϯάςʔϒϧ಺ͷશϦετʢarrayʣ % ୈೋҾ਺ : ѼઌͷIPʢintegerʣ %

    ୈࡾҾ਺ : ૹ৴ઌީิʢѼઌͱ൑அ͞Εͨʣͷϧʔτ৘ใʢarrayʣ match_dest_ip([], _, List) -> List; match_dest_ip([{_, _, _, Ip, _, Subnetmask, Ad, Metric, Nexthop, _, If}| Tail], DestIp, List) when is_integer(DestIp) -> case DestIp band Subnetmask of Ip -> match_dest_ip(Tail, DestIp, [{If, Nexthop, Subnetmask, Ad, Metric}|List]); _ -> match_dest_ip(Tail, DestIp, List) end. 2. 1ͷ݁ՌͱIp͕౳͍͔͠Ͳ͏͔ ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ ౰ͯ͸·ͬͯΔ΋ͷͷϦετΛऔಘ
  40. ϧʔςΟϯάॲཧ 2. 1Ͱऔಘͨ͠ϧʔτ৘ใ͔ΒҰ൪༏ઌ౓ͷߴ͍
 ϧʔτ৘ใΛऔಘ 1. ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ Ϛον͢ΔϦετΛऔಘ 3. 2Ͱऔಘͨ͠ϧʔτ৘ใͷωΫετϗοϓ
 ʹૹ৴͢Δ

  41. ϧʔςΟϯάॲཧ • ѼઌͱͳΔϧʔτ৘ใΛ࠶ؼॲཧʹͯऔಘɺͦͷ࣌ͷ༏ઌ౓ 1. ૹ৴ઌIP͕௚઀ܨ͕͍ͬͯΔωοτϫʔΫʹؚ·Ε͍ͯΔ΋ͷ 2. αϒωοτϚεΫʢϓϨϑΟοΫε௕ʣ͕Ұ൪௕͍΋ͷ 3. αϒωοτϚεΫ͕౳͘͠ AD஋͕খ͍͞΋ͷ

    4. αϒωοτϚεΫɺAD஋͕౳͘͠ɺϝτϦοΫ͕খ͍͞΋ͷ
  42. ϧʔςΟϯάॲཧ ѼઌIP͕௚઀ܨ͕͍ͬͯΔωοτϫʔΫʹؚ·Ε͍ͯΔ΋ͷ ϧʔτ৘ใͷѼઌ͕ʮNEXTHOP_DIRECTʯͷ৔߹͸௚઀ܨ͕͍ͬͯΔωοτϫʔΫ಺ʹ
 ଐ͍ͯ͠Δʢ৘ใݯ͕ʮCʯͷ΋ͷʣ AD͕0ͷ৔߹͸௚઀ܨ͕͍ͬͯΔωοτϫʔΫ಺ʹଐ͍ͯ͠Δʢ৘ใݯ͕ʮCʯͷ΋ͷʣ %% fetch to destination route

    % ୈҰҾ਺ : ϧʔτ৘ใʢarrayʣ % ୈೋҾ਺ : ݱࡏͷҰ൪༏ઌ౓͕ߴ͍ϧʔτ৘ใ fetch_dest_route([{_, ?NEXTHOP_DIRECT, _, _, _}=Route| _], _) -> Route; % ad 0 fetch_dest_route([{_, _, _, 0, _}=Route| _], _) -> Route; ௚઀ܨ͕͍ͬͯΔωοτϫʔΫ
  43. ϧʔςΟϯάॲཧ ݱࡏͷϧʔτ৘ใΑΓαϒωοτϚεΫ͕௕͍ϧʔτ৘ใ͕
 ͋Δ৔߹ɺҰ൪༏ઌ౓͕ߴ͍΋ͷͱ͢Δ %% fetch to destination route % ୈҰҾ਺

    : ϧʔτ৘ใʢarrayʣ % ୈೋҾ਺ : ݱࡏͷҰ൪༏ઌ౓͕ߴ͍ϧʔτ৘ใ fetch_dest_route([{_, _, Subnet, _, _}=Route| Tail],{_, _, NowSubnet, _, _}) when Subnet > NowSubnet -> fetch_dest_route(Tail, Route); αϒωοτϚεΫͷൺֱ
  44. ϧʔςΟϯάॲཧ ݱࡏͷϧʔτ৘ใͱൺֱ͠αϒωοτϚεΫ͕౳͘͠
 AD஋͕খ͍͞৔߹Ұ൪༏ઌ౓͕ߴ͍΋ͷͱ͢Δ %% fetch to destination route % ୈҰҾ਺

    : ϧʔτ৘ใʢarrayʣ % ୈೋҾ਺ : ݱࡏͷҰ൪༏ઌ౓͕ߴ͍ϧʔτ৘ใ fetch_dest_route([{_, _, Subnet, Ad, _}=Route| Tail], {_, _, Subnet, NowAd, _}) when Ad < NowAd -> fetch_dest_route(Tail, Route); AD஋Λൺֱ
  45. ϧʔςΟϯάॲཧ ݱࡏͷϧʔτ৘ใͱൺֱ͠αϒωοτϚεΫͱAD஋͕౳͘͠
 ϝτϦοΫ͕খ͍͞৔߹Ұ൪༏ઌ౓͕ߴ͍΋ͷͱ͢Δ %% fetch to destination route % ୈҰҾ਺

    : ϧʔτ৘ใʢarrayʣ % ୈೋҾ਺ : ݱࡏͷҰ൪༏ઌ౓͕ߴ͍ϧʔτ৘ใ fetch_dest_route([{_, _, Subnet, Ad, Metric}=Route| Tail],{_, _, Subnet, Ad, NowMetric}) when Metric < NowMetric -> fetch_dest_route(Tail, Route); ϝτϦοΫΛൺֱ
  46. ϧʔςΟϯάॲཧ 2. 1Ͱऔಘͨ͠ϧʔτ৘ใ͔ΒҰ൪༏ઌ౓ͷߴ͍
 ϧʔτ৘ใΛऔಘ 1. ૹ৴ઌIP͕ϧʔςΟϯάςʔϒϧͷѼઌϧʔτʹ Ϛον͢ΔϦετΛऔಘ 3. 2Ͱऔಘͨ͠ϧʔτ৘ใͷωΫετϗοϓ
 ʹૹ৴͢Δ

  47. ϧʔςΟϯάॲཧ ARPςʔϒϧ͔ΒωΫετϗοϓͷIPʹඥͮ͘ɺMACΞυϨεΛ
 औಘ͢Δ get_mac_addr({_, Nexthop}) -> % ARPςʔϒϧ͔ΒωΫετϗοϓʹඥͮ͘MACΞυϨεΛऔಘ case brook_arp_table:fetch_dest_mac_addr(Nexthop,

    false) of % ଘࡏͯ͠ͳ͍৔߹͸ɺʮundefinedʯΛฦ͢ [] -> undefined; % ଘࡏͯ͠Δ৔߹͸ɺMACΞυϨεΛฦ͢ [{arp_table, _, _, DestMac, _}| _] -> DestMac end.
  48. ϧʔςΟϯάॲཧ L2ϔομʔͷૹ৴ઌMACΞυϨεΛωΫετϗοϓɺ
 ૹ৴ݩMACΞυϨεΛࣗ෼ࣗ਎ʢΠϯλʔϑΣΠεʣ΁ͱ
 ॻ͖׵͑Δ ip_request(FD, #{source_mac := SourceMac, dest_mac :=

    DestMac}=Opt, Data) -> Ethernet = ethernet_to_binary(#ethernet_header{ source_mac_addr=tuple_to_list(SourceMac), dest_mac_addr=DestMac, type=?TYPE_IP} ), request(FD, <<Ethernet/bitstring, Data/bitstring>>, Opt) L2ͷύέοτϔομʔΛ࡞੒
  49. Ϟδϡʔϧ࣮૷ ʢElixirʣ

  50. ϧʔλʹ֦ுੑΛ࣋ͨͤΔͨΊɺ ErlangͰPipelineॲཧͷ
 ࣮૷Λ͠·ͨ͠

  51. Pipelineॲཧͷ৔ॴ ύέοτͷड৴ -͕*1͔֬ೝ νΣοΫαϜͷ֬ೝ 55-Λ 55-͕͔Ͳ͏͔֬ೝ νΣοΫαϜͷ࠶ܭࢉ ωΫετϗοϓͷ."$ ΞυϨεͷऔಘ -ͷϔομʔΛ࡞੒

    ύέοτΛૹ৴ -ͷॲཧ ϧʔςΟϯάςʔϒϧ ͔Βϧʔτ৘ใΛऔಘ     
  52. Pipelineॲཧͷ৔ॴ 1. IPύέοτͷॲཧલ 2. L4ϨΠϠʔͷॲཧલ 3. L4ϨΠϠʔͷॲཧޙ 4. IPύέοτͷॲཧޙ 5.

    ύέοτͷૹ৴ޙ
  53. Ϟδϡʔϧͱ࣮ͯ͠૷ͨ͠΋ͷ • FirewallʢPipelineΛར༻ʣ • ύέοτϩεʢPipelineΛར༻ʣ • ϦϓϥΠʢPipelineΛར༻ʣ • ஗Ԇૹ৴ʢPipelineΛར༻ʣ •

    ελςΟοΫϧʔςΟϯάͷΠϯλʔϑΣΠε
  54. FirewallϞδϡʔϧͷ ࣮૷ྫ

  55. FirewallϞδϡʔϧ ύέοτͷड৴ -͕*1͔֬ೝ νΣοΫαϜͷ֬ೝ 55-Λ 55-͕͔Ͳ͏͔֬ೝ νΣοΫαϜͷ࠶ܭࢉ ωΫετϗοϓͷ."$ ΞυϨεͷऔಘ -ͷϔομʔΛ࡞੒

    ύέοτΛૹ৴ -ͷॲཧ ϧʔςΟϯάςʔϒϧ ͔Βϧʔτ৘ใΛऔಘ ͜͜ʹFirewallͷॲཧΛPipelineͱͯ͠௥Ճ͢Δ
  56. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end;
  57. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end; PipelineʹॲཧΛొ࿥
  58. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end; Pipelineͷ࣮ߦ
  59. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end; Pipelineʹొ࿥ͨ͠ॲཧΛ࣮ߦ͍ͯ͘͠
  60. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end; FuncʢϝιουʣΛ [Data0, Opt0] ͷҾ਺Ͱ࣮ߦ͢Δ
  61. FirewallϞδϡʔϧ • ४උɿErlangଆͰPipelineॲཧΛ࣮ߦͰ͖ΔΑ͏ʹ͢Δ save_before_ip_pipeline(Func) when is_function(Func, 2) -> mnesia:transaction(fun() ->

    mnesia:write(pipeline, #pipeline{type=?BEFORE_IP, module=undefined, func=Func}, write) end) before_ip_pipeline(Data, Opt) -> Filter = mnesia:dirty_match_object(pipeline, {'_', ?BEFORE_IP, '$1', '$2'} ), pipeline(Filter, Data, Opt) pipeline([#pipeline{module=undefined, func=Func}| Tail], Data0, Opt0) -> case apply(Func, [Data0, Opt0]) of {error, Msg} -> {error, Msg}; {ok, Data, Opt} -> pipeline(Tail, Data, Opt) end; Τϥʔͷ৔߹͸ΤϥʔͱͳΓɺύέοτͷ ϧʔςΟϯάΛߦΘͳ͍ ਖ਼ৗͷ৔߹͸ɺ࣍ͷPipelineॲཧΛ࣮ߦ
  62. Elixirଆͷ࣮૷

  63. FirewallϞδϡʔϧ • Firewallͷ৚݅ΛϝλϓϩάϥϜͰ࣮૷ firewall :default do allow( source_ip: {192, 168,

    20, 0}, source_netmask: {255, 255, 255, 0}, protocol: :ip ) allow( source_ip: {192, 168, 40, 0}, source_netmask: {255, 255, 255, 0}, protocol: :tcp ) deny() end
  64. FirewallϞδϡʔϧ • Firewallͷ৚݅ΛϝλϓϩάϥϜͰ࣮૷ firewall :default do allow( source_ip: {192, 168,

    20, 0}, source_netmask: {255, 255, 255, 0}, protocol: :ip ) allow( source_ip: {192, 168, 40, 0}, source_netmask: {255, 255, 255, 0}, protocol: :tcp ) deny() end ڐՄ͢Δύέοτ৘ใ ʢૹ৴ݩIPͱ͔ϓϩτίϧͱ͔ʣ
  65. FirewallϞδϡʔϧ • Firewallͷ৚݅ΛϝλϓϩάϥϜͰ࣮૷ firewall :default do allow( source_ip: {192, 168,

    20, 0}, source_netmask: {255, 255, 255, 0}, protocol: :ip ) allow( source_ip: {192, 168, 40, 0}, source_netmask: {255, 255, 255, 0}, protocol: :tcp ) deny() end શͯͷύέοτΛڋ൱͢Δ
  66. FirewallϞδϡʔϧ • Firewallॲཧͷొ࿥ defmacro firewall_through(identifier) do quote do identifier =

    unquote(identifier) :brook_pipeline.save_before_ip_pipeline(Eshe.Firewall.firewall_filter(identifier)) end end def firewall_filter(identifier) do filter = fetch_filter(Eshe.Supervisor.route_firewall(), identifier) fn data, option -> case is_allow_filter(filter, data) do :ok -> {:ok, data, option} error -> {:error, error} end end end
  67. FirewallϞδϡʔϧ • Firewallॲཧͷొ࿥ defmacro firewall_through(identifier) do quote do identifier =

    unquote(identifier) :brook_pipeline.save_before_ip_pipeline(Eshe.Firewall.firewall_filter(identifier)) end end def firewall_filter(identifier) do filter = fetch_filter(Eshe.Supervisor.route_firewall(), identifier) fn data, option -> case is_allow_filter(filter, data) do :ok -> {:ok, data, option} error -> {:error, error} end end end firewall_filterΛొ࿥͢Δ
  68. FirewallϞδϡʔϧ • Firewallॲཧͷొ࿥ defmacro firewall_through(identifier) do quote do identifier =

    unquote(identifier) :brook_pipeline.save_before_ip_pipeline(Eshe.Firewall.firewall_filter(identifier)) end end def firewall_filter(identifier) do filter = fetch_filter(Eshe.Supervisor.route_firewall(), identifier) fn data, option -> case is_allow_filter(filter, data) do :ok -> {:ok, data, option} error -> {:error, error} end end end Erlangଆ΁ॲཧΛฦ͠ɺΤϥʔͷ৔߹͸ ύέοτͷॲཧΛऴྃͤ͞Δ
  69. FirewallϞδϡʔϧ • Firewallͷ൑ఆॲཧ def match( %{protocol: protocol} = record, <<version::size(4),

    len::size(4), _head::size(88), source_ip::size(32), dest_ip::size(32), other::binary>> ) when protocol in [:tcp, :udp] do {source_port, dest_port} = fetch_port(len, other) with res <- match_ip([], record[:dest_ip], record[:dest_netmask], dest_ip), res <- match_ip(res, record[:source_ip], record[:source_netmask], source_ip), res <- match_port(res, record[:source_port], source_port), res <- match_port(res, record[:dest_port], dest_port), res <- Enum.filter(res, &(&1 != nil)), {:ok, _value} <- Enum.fetch(res, 0) do Enum.all?(res, fn r -> r == true end) else _ -> false end end
  70. FirewallϞδϡʔϧ • Firewallͷ൑ఆॲཧ def match( %{protocol: protocol} = record, <<version::size(4),

    len::size(4), _head::size(88), source_ip::size(32), dest_ip::size(32), other::binary>> ) when protocol in [:tcp, :udp] do {source_port, dest_port} = fetch_port(len, other) with res <- match_ip([], record[:dest_ip], record[:dest_netmask], dest_ip), res <- match_ip(res, record[:source_ip], record[:source_netmask], source_ip), res <- match_port(res, record[:source_port], source_port), res <- match_port(res, record[:dest_port], dest_port), res <- Enum.filter(res, &(&1 != nil)), {:ok, _value} <- Enum.fetch(res, 0) do Enum.all?(res, fn r -> r == true end) else _ -> false end end ૹ৴ݩͱૹ৴ઌͷIP ૹ৴ݩͱૹ৴ઌͷϙʔτ
  71. FirewallϞδϡʔϧ • Firewallͷ൑ఆॲཧ def match( %{protocol: protocol} = record, <<version::size(4),

    len::size(4), _head::size(88), source_ip::size(32), dest_ip::size(32), other::binary>> ) when protocol in [:tcp, :udp] do {source_port, dest_port} = fetch_port(len, other) with res <- match_ip([], record[:dest_ip], record[:dest_netmask], dest_ip), res <- match_ip(res, record[:source_ip], record[:source_netmask], source_ip), res <- match_port(res, record[:source_port], source_port), res <- match_port(res, record[:dest_port], dest_port), res <- Enum.filter(res, &(&1 != nil)), {:ok, _value} <- Enum.fetch(res, 0) do Enum.all?(res, fn r -> r == true end) else _ -> false end end શͯͷൺֱ݁Ռ͕౳͍͠৔߹ͷΈtrueʹ
  72. ·ͱΊ

  73. ϧʔςΟϯάΛཧղ͢Ε͹ ϧʔλͷ͜ͱ͕Θ͔Γ ωοτϫʔΫͷ͜ͱ΋ ෼͔ͬͯ͘ΔͷͰ͸ɾɾɾ

  74. Θ͔Βͳ͍͜ͱ͕ ·ͩ·ͩଟ͍ʂʂʂʂ

  75. ΍Εͯͳ͍͜ͱ

  76. ΍Εͯͳ͍͜ͱ • ϧʔςΟϯάϓϩτίϧͷ࣮૷ʢRIPͱ͔BGPͱ͔OSPFͱ͔ʣ

  77. ΍Εͯͳ͍͜ͱ • ϧʔςΟϯάϓϩτίϧͷ࣮૷ʢRIPͱ͔BGPͱ͔OSPFͱ͔ʣ • ϩϯήετϚονΞϧΰϦζϜͷ࣮૷

  78. ΍Εͯͳ͍͜ͱ • ϧʔςΟϯάϓϩτίϧͷ࣮૷ʢRIPͱ͔BGPͱ͔OSPFͱ͔ʣ • ϩϯήετϚονΞϧΰϦζϜͷ࣮૷ • VRRPͷ࣮૷

  79. ΍Εͯͳ͍͜ͱ • ϧʔςΟϯάϓϩτίϧͷ࣮૷ʢRIPͱ͔BGPͱ͔OSPFͱ͔ʣ • ϩϯήετϚονΞϧΰϦζϜͷ࣮૷ • VRRPͷ࣮૷ • ARPΛ·ͩҰ෦͔࣮͠૷ͯ͠ͳ͍ɺɺɺ

  80. ΍Εͯͳ͍͜ͱ • ϧʔςΟϯάϓϩτίϧͷ࣮૷ʢRIPͱ͔BGPͱ͔OSPFͱ͔ʣ • ϩϯήετϚονΞϧΰϦζϜͷ࣮૷ • VRRPͷ࣮૷ • ARPΛ·ͩҰ෦͔࣮͠૷ͯ͠ͳ͍ɺɺɺ •

    IPSec΋࣮૷͓͖͍ͯͨ͠ʂʂ
  81. ·ͩ·ͩ΍Δ͜ͱ͕ ͍ͬͺ͍ɾɾɾ

  82. ͨͩগ͠͸ϧʔλͷ͜ͱɺ
 ωοτϫʔΫͷ͜ͱ͕
 Θ͔ͬͨؾ͕͢Δɾɾɾʂ

  83. PHPer͔Βͷ ωοτϫʔΫʢϧʔλʣ ͷ࿩Ͱͨ͠

  84. ͝੩ௌ͋Γ͕ͱ͏
 ͍͟͝·ͨ͠