From 4f6d84ff9ef35c2e73d0b527f44e7f2597c4559a Mon Sep 17 00:00:00 2001 From: Kirat Pandya Date: Sat, 22 Apr 2017 18:36:17 -0700 Subject: [PATCH 1/2] Adding support for EdgeMax clients Known issues 1) IPV6 is untested, probably broken 2) multiple clients connecting to the server seems to break routing. --- config.cfg | 6 ++ docs/client-edgemax.md | 109 +++++++++++++++++++++++ roles/vpn/templates/client_ipsec.conf.j2 | 17 +++- roles/vpn/templates/ipsec.conf.j2 | 4 + roles/vpn/templates/rules.v4.j2 | 12 +++ 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 docs/client-edgemax.md diff --git a/config.cfg b/config.cfg index fde48393..af0fb776 100644 --- a/config.cfg +++ b/config.cfg @@ -38,6 +38,12 @@ CA_PayloadIdentifier: "{{ 700000 | random | to_uuid | upper }}" # Block traffic between connected clients BetweenClients_DROP: Y +# ALPHA feature: Uncomment below to build EdgeMaxclient configuration. Note that this will break connectivity from other clients +# We recommend that you deploy a sepearate Algo server for each Edgerouter with only one client user defined. +# Set the lan subnet to the IP CIDR notation for the lan behind the router. This MUST not interest with the vpn_network set above +edgemax_support: True +edgemax_lan_subnet: 10.0.0.0/16 + congrats: common: | "# Congratulations! #" diff --git a/docs/client-edgemax.md b/docs/client-edgemax.md new file mode 100644 index 00000000..c736de4f --- /dev/null +++ b/docs/client-edgemax.md @@ -0,0 +1,109 @@ +# Setting up an EdgeMax Client + +Steps + +1) Set up config.cfg + * one single user + * Uncomment ```edgemax_support``` and ```edgemax_lan_subnet``` and make sure the LAN subnet is correct and does not overlapt with ```vpn_network``` + * +2) Copy over files to router and place them as follows. This will preserve the files if you upgrade the router image + * config//ipsec_.* /config/user-data + * config//pki/cacert.pem /config/auth/algo/cacerts/ + * config//pki/certs/*.crt /config/auth/algo/certs/ + * config//pki/private/.key /config/auth/algo/private/ +3) SSH into the router and copy files from the config folder to the ipsec.d configuration folders. You will have to do this step every time you upgrade the router image. + * /config/auth/algo/cacerts/cacert.pem /etc/ipsec.d/cacerts + * /config/auth/algo/certs/* /etc/ipsec.d/certs + * /config/auth/algo/private/* /etc/ipsec.d/private (needs sudo) +4) Still on the router, edit /config/config.boot and add the following: + + ``` + vpn { + ipsec { + auto-update 3600 + auto-firewall-nat-exclude disable + include-ipsec-conf /config/user-data/ipsec_home.conf + include-ipsec-secrets /config/user-data/ipsec_home.secrets + logging { + log-level 2 + log-modes net + } + + } + } + ``` +5) ```sudo ipsec restart``` +6) ```sudo ipsec statusall``` - At this point you should see a shunted connection in the output. If not, stop and verify the above steps. Proceeding without the shunted connection will break local routing if the tunnel fails to come up + ``` + Listening IP addresses: + + + + Connections: + ikev2-: %any... IKEv2, dpddelay=35s + ikev2-: local: [CN=home] uses public key authentication + ikev2-: cert: "CN=home" + ikev2-: remote: [] uses public key authentication + ikev2-: child: 10.0.0.0/16 === 0.0.0.0/0 TUNNEL, dpdaction=clear + lanbypass: %any...%any IKEv1 + lanbypass: local: uses public key authentication + lanbypass: remote: uses public key authentication + lanbypass: child: 10.0.0.0/16 === 10.0.0.0/16 PASS + Shunted Connections: + lanbypass: 10.0.0.0/16 === 10.0.0.0/16 PASS + Security Associations (0 up, 0 connecting): + none + ``` +7) ```sudo ipsec up ikev2-``` - the tunnel should come up + ``` + @ubnt:/$ sudo ipsec status + Shunted Connections: + lanbypass: 10.0.0.0/16 === 10.0.0.0/16 PASS + Security Associations (1 up, 0 connecting): + ikev2-[1]: ESTABLISHED 11 minutes ago, 24.18.46.13[CN=home]...[] + ikev2-{1}: INSTALLED, TUNNEL, ESP in UDP SPIs: c5fbcf80_i cdffe66d_o + ikev2-{1}: 10.0.0.0/16 === 0.0.0.0/0 + ``` +8) Now, we need to make sure that packets meant to go into the tunnel are not modified by SNAT rules. Go to the web inteface and under Firewall/Nat > NAT, update the masquarade rule to only filter for Destination = ALGO_IP. Below it what it looks like in the config.boot file/UI tree. THe second rule below is an example of how you can exclude a client's traffic comeletely from the tunnel. + ``` + nat { + rule 5003 { + description "masquerade for WAN" + destination { + address + } + log disable + outbound-interface eth0 + protocol all + type masquerade + } + rule 5005 { + description "Masquerade for WAN - Xbox One" + destination { + } + log disable + outbound-interface eth0 + protocol tcp + source { + address 10.0.0.35 + } + type masquerade + } + } + ``` +9) You can try enabling ipsec hardware offload in the UI config tree under system. This seemsto be buggy and in some cases results in throughput lower than when offload is disabled - YMMV + ``` + offload { + hwnat disable + ipsec enable + ipv4 { + forwarding enable + gre disable + vlan enable + } + ipv6 { + forwarding enable + vlan enable + } + } + ``` diff --git a/roles/vpn/templates/client_ipsec.conf.j2 b/roles/vpn/templates/client_ipsec.conf.j2 index 7fde04ab..7ee33f0a 100644 --- a/roles/vpn/templates/client_ipsec.conf.j2 +++ b/roles/vpn/templates/client_ipsec.conf.j2 @@ -24,5 +24,18 @@ conn ikev2-{{ IP_subject_alt_name }} leftcert={{ item }}.crt leftfirewall=yes left=%defaultroute - - auto=add +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} + leftsubnet={{ edgemax_lan_subnet }} + auto=route +{% else %} + audto=add +{% endif %} + + +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} +conn lanbypass + leftsubnet={{ edgemax_lan_subnet }} + rightsubnet={{ edgemax_lan_subnet }} + type=passthrough + auto=route +{% endif %} diff --git a/roles/vpn/templates/ipsec.conf.j2 b/roles/vpn/templates/ipsec.conf.j2 index 36dc3176..a654adae 100644 --- a/roles/vpn/templates/ipsec.conf.j2 +++ b/roles/vpn/templates/ipsec.conf.j2 @@ -38,5 +38,9 @@ conn %default rightdns={% for host in dns_servers.ipv4 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% if ipv6_support is defined and ipv6_support == "yes" %},{% for host in dns_servers.ipv6 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% endif %} {% endif %} +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} + rightsubnet=0.0.0.0/0,::/0 +{% endif %} + conn ikev2-pubkey auto=add diff --git a/roles/vpn/templates/rules.v4.j2 b/roles/vpn/templates/rules.v4.j2 index 5ced4eeb..bf056d9d 100644 --- a/roles/vpn/templates/rules.v4.j2 +++ b/roles/vpn/templates/rules.v4.j2 @@ -6,12 +6,18 @@ :POSTROUTING ACCEPT [0:0] {% if max_mss is defined %} -A FORWARD -s {{ vpn_network }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ max_mss }} +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} +-A FORWARD -s {{ edgemax_lan_subnet }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ max_mss }} +{% endif %} {% endif %} COMMIT *nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s {{ vpn_network }} -m policy --pol none --dir out -j MASQUERADE +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} +-A POSTROUTING -s {{ edgemax_lan_subnet }} -m policy --pol none --dir out -j MASQUERADE +{% endif %} COMMIT *filter :INPUT DROP [0:0] @@ -34,11 +40,17 @@ COMMIT -A INPUT -d {{ local_service_ip }} -p tcp -m multiport --dport 8080,8118 -j ACCEPT {% if BetweenClients_DROP is defined and BetweenClients_DROP == "Y" %} -A FORWARD -s {{ vpn_network }} -d {{ vpn_network }} -j DROP +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} +-A FORWARD -s {{ edgemax_lan_subnet }} -d {{ edgemax_lan_subnet }} -j DROP +{% endif %} {% endif %} -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p tcp --dport 445 -j DROP -A FORWARD -p udp -m multiport --ports 137,138 -j DROP -A FORWARD -p tcp -m multiport --ports 137,139 -j DROP -A FORWARD -m conntrack --ctstate NEW -s {{ vpn_network }} -m policy --pol ipsec --dir in -j ACCEPT +{% if edgemax_support is defined and edgemax_lan_subnet is defined and edgemax_support == True %} +-A FORWARD -m conntrack --ctstate NEW -s {{ edgemax_lan_subnet }} -m policy --pol ipsec --dir in -j ACCEPT +{% endif %} COMMIT From b7a7fd6b4f54f917ed3d49e39b3db65e98ca8eb4 Mon Sep 17 00:00:00 2001 From: Kirat Pandya Date: Wed, 3 May 2017 21:30:15 -0700 Subject: [PATCH 2/2] Fixing feedback Typo in client_ipsec.conf Disabling by default --- config.cfg | 4 ++-- roles/vpn/templates/client_ipsec.conf.j2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config.cfg b/config.cfg index af0fb776..61a5a96a 100644 --- a/config.cfg +++ b/config.cfg @@ -41,8 +41,8 @@ BetweenClients_DROP: Y # ALPHA feature: Uncomment below to build EdgeMaxclient configuration. Note that this will break connectivity from other clients # We recommend that you deploy a sepearate Algo server for each Edgerouter with only one client user defined. # Set the lan subnet to the IP CIDR notation for the lan behind the router. This MUST not interest with the vpn_network set above -edgemax_support: True -edgemax_lan_subnet: 10.0.0.0/16 +#edgemax_support: True +#edgemax_lan_subnet: 10.0.0.0/16 congrats: common: | diff --git a/roles/vpn/templates/client_ipsec.conf.j2 b/roles/vpn/templates/client_ipsec.conf.j2 index 7ee33f0a..0d421c57 100644 --- a/roles/vpn/templates/client_ipsec.conf.j2 +++ b/roles/vpn/templates/client_ipsec.conf.j2 @@ -28,7 +28,7 @@ conn ikev2-{{ IP_subject_alt_name }} leftsubnet={{ edgemax_lan_subnet }} auto=route {% else %} - audto=add + auto=add {% endif %}