summaryrefslogtreecommitdiff
path: root/src/etc
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc')
-rw-r--r--src/etc/dhcp/dhclient-exit-hooks.d/ipsec-dhclient-hook46
-rw-r--r--src/etc/ipsec.d/key-pair.template67
-rwxr-xr-xsrc/etc/ipsec.d/vti-up-down47
-rwxr-xr-xsrc/etc/opennhrp/opennhrp-script.py136
-rw-r--r--src/etc/systemd/system/conntrackd.service.d/override.conf8
-rwxr-xr-xsrc/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py29
6 files changed, 318 insertions, 15 deletions
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/ipsec-dhclient-hook
new file mode 100644
index 000000000..36edf04f3
--- /dev/null
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/ipsec-dhclient-hook
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+from vyos.util import call
+
+IPSEC_CONF="/etc/ipsec.conf"
+IPSEC_SECRETS="/etc/ipsec.secrets"
+
+def getlines(file):
+ with open(file, 'r') as f:
+ return f.readlines()
+
+def writelines(file, lines):
+ with open(file, 'w') as f:
+ f.writelines(lines)
+
+if __name__ == '__main__':
+ interface = os.getenv('interface')
+ new_ip = os.getenv('new_ip_address')
+ old_ip = os.getenv('old_ip_address')
+ reason = os.getenv('reason')
+
+ if (old_ip == new_ip and reason != 'BOUND') or reason in ['REBOOT', 'EXPIRE']:
+ sys.exit(0)
+
+ conf_lines = getlines(IPSEC_CONF)
+ secrets_lines = getlines(IPSEC_SECRETS)
+ found = False
+ to_match = f'# dhcp:{interface}'
+
+ for i, line in enumerate(conf_lines):
+ if line.find(to_match) > 0:
+ conf_lines[i] = line.replace(old_ip, new_ip)
+ found = True
+
+ for i, line in enumerate(secrets_lines):
+ if line.find(to_match) > 0:
+ secrets_lines[i] = line.replace(old_ip, new_ip)
+
+ if found:
+ writelines(IPSEC_CONF, conf_lines)
+ writelines(IPSEC_SECRETS, secrets_lines)
+ call('sudo /usr/sbin/ipsec rereadall')
+ call('sudo /usr/sbin/ipsec reload')
diff --git a/src/etc/ipsec.d/key-pair.template b/src/etc/ipsec.d/key-pair.template
new file mode 100644
index 000000000..56be97516
--- /dev/null
+++ b/src/etc/ipsec.d/key-pair.template
@@ -0,0 +1,67 @@
+[ req ]
+ default_bits = 2048
+ default_keyfile = privkey.pem
+ distinguished_name = req_distinguished_name
+ string_mask = utf8only
+ attributes = req_attributes
+ dirstring_type = nobmp
+# SHA-1 is deprecated, so use SHA-2 instead.
+ default_md = sha256
+# Extension to add when the -x509 option is used.
+ x509_extensions = v3_ca
+
+[ req_distinguished_name ]
+ countryName = Country Name (2 letter code)
+ countryName_min = 2
+ countryName_max = 2
+ ST = State Name
+ localityName = Locality Name (eg, city)
+ organizationName = Organization Name (eg, company)
+ organizationalUnitName = Organizational Unit Name (eg, department)
+ commonName = Common Name (eg, Device hostname)
+ commonName_max = 64
+ emailAddress = Email Address
+ emailAddress_max = 40
+[ req_attributes ]
+ challengePassword = A challenge password (optional)
+ challengePassword_min = 4
+ challengePassword_max = 20
+[ v3_ca ]
+ subjectKeyIdentifier=hash
+ authorityKeyIdentifier=keyid:always,issuer:always
+ basicConstraints = critical, CA:true
+ keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+[ v3_intermediate_ca ]
+# Extensions for a typical intermediate CA (`man x509v3_config`).
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ basicConstraints = critical, CA:true, pathlen:0
+ keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+[ usr_cert ]
+# Extensions for client certificates (`man x509v3_config`).
+ basicConstraints = CA:FALSE
+ nsCertType = client, email
+ nsComment = "OpenSSL Generated Client Certificate"
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid,issuer
+ keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+ extendedKeyUsage = clientAuth, emailProtection
+[ server_cert ]
+# Extensions for server certificates (`man x509v3_config`).
+ basicConstraints = CA:FALSE
+ nsCertType = server
+ nsComment = "OpenSSL Generated Server Certificate"
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid,issuer:always
+ keyUsage = critical, digitalSignature, keyEncipherment
+ extendedKeyUsage = serverAuth
+[ crl_ext ]
+# Extension for CRLs (`man x509v3_config`).
+ authorityKeyIdentifier=keyid:always
+[ ocsp ]
+# Extension for OCSP signing certificates (`man ocsp`).
+ basicConstraints = CA:FALSE
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid,issuer
+ keyUsage = critical, digitalSignature
+ extendedKeyUsage = critical, OCSPSigning
diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down
new file mode 100755
index 000000000..0e1cd7753
--- /dev/null
+++ b/src/etc/ipsec.d/vti-up-down
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+## Script called up strongswan to bring the vti interface up/down based on the state of the IPSec tunnel.
+## Called as vti_up_down vti_intf_name
+
+import os
+import sys
+
+from vyos.util import call, get_interface_config, get_interface_address
+
+def get_dhcp_address(interface):
+ addr = get_interface_address(interface)
+ if not addr:
+ return None
+ if len(addr['addr_info']) == 0:
+ return None
+ return addr['addr_info'][0]['local']
+
+if __name__ == '__main__':
+ verb = os.getenv('PLUTO_VERB')
+ connection = os.getenv('PLUTO_CONNECTION')
+ interface = sys.argv[1]
+ dhcp_interface = sys.argv[2]
+
+ print(f'vti-up-down: start: {verb} {connection} {interface}')
+
+ if verb in ['up-client', 'up-host']:
+ call('sudo ip route delete default table 220')
+
+ vti_link = get_interface_config(interface)
+
+ if not vti_link:
+ print('vti-up-down: interface not found')
+ sys.exit(0)
+
+ vti_link_up = (vti_link['operstate'] == 'UP' if 'operstate' in vti_link else False)
+
+ if verb in ['up-client', 'up-host']:
+ if not vti_link_up:
+ if dhcp_interface != 'no':
+ local_ip = get_dhcp_address(dhcp_interface)
+ call(f'sudo ip tunnel change {interface} local {local_ip}')
+ call(f'sudo ip link set {interface} up')
+ elif verb in ['down-client', 'down-host']:
+ if vti_link_up:
+ call(f'sudo ip link set {interface} down')
+
+ print('vti-up-down: finish') \ No newline at end of file
diff --git a/src/etc/opennhrp/opennhrp-script.py b/src/etc/opennhrp/opennhrp-script.py
new file mode 100755
index 000000000..f7487ee5f
--- /dev/null
+++ b/src/etc/opennhrp/opennhrp-script.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from pprint import pprint
+import os
+import re
+import sys
+import vici
+
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+NHRP_CONFIG="/run/opennhrp/opennhrp.conf"
+
+def parse_type_ipsec(interface):
+ with open(NHRP_CONFIG, 'r') as f:
+ lines = f.readlines()
+ match = rf'^interface {interface} #(hub|spoke)(?:\s([\w-]+))?$'
+ for line in lines:
+ m = re.match(match, line)
+ if m:
+ return m[1], m[2]
+ return None, None
+
+def vici_initiate(conn, child_sa, src_addr, dest_addr):
+ try:
+ session = vici.Session()
+ logs = session.initiate({
+ 'ike': conn,
+ 'child': child_sa,
+ 'timeout': '-1',
+ 'my-host': src_addr,
+ 'other-host': dest_addr
+ })
+ for log in logs:
+ message = log['msg'].decode('ascii')
+ print('INIT LOG:', message)
+ return True
+ except:
+ return None
+
+def vici_terminate(conn, child_sa, src_addr, dest_addr):
+ try:
+ session = vici.Session()
+ logs = session.terminate({
+ 'ike': conn,
+ 'child': child_sa,
+ 'timeout': '-1',
+ 'my-host': src_addr,
+ 'other-host': dest_addr
+ })
+ for log in logs:
+ message = log['msg'].decode('ascii')
+ print('TERM LOG:', message)
+ return True
+ except:
+ return None
+
+def iface_up(interface):
+ cmd(f'sudo ip route flush proto 42 dev {interface}')
+ cmd(f'sudo ip neigh flush dev {interface}')
+
+def peer_up(dmvpn_type, conn):
+ src_addr = os.getenv('NHRP_SRCADDR')
+ src_nbma = os.getenv('NHRP_SRCNBMA')
+ dest_addr = os.getenv('NHRP_DESTADDR')
+ dest_nbma = os.getenv('NHRP_DESTNBMA')
+ dest_mtu = os.getenv('NHRP_DESTMTU')
+
+ if dest_mtu:
+ args = cmd(f'sudo ip route get {dest_nbma} from {src_nbma}')
+ cmd(f'sudo ip route add {args} proto 42 mtu {dest_mtu}')
+
+ if conn and dmvpn_type == 'spoke' and process_named_running('charon'):
+ vici_terminate(conn, 'dmvpn', src_nbma, dest_nbma)
+ vici_initiate(conn, 'dmvpn', src_nbma, dest_nbma)
+
+def peer_down(dmvpn_type, conn):
+ src_nbma = os.getenv('NHRP_SRCNBMA')
+ dest_nbma = os.getenv('NHRP_DESTNBMA')
+
+ if conn and dmvpn_type == 'spoke' and process_named_running('charon'):
+ vici_terminate(conn, 'dmvpn', src_nbma, dest_nbma)
+
+ cmd(f'sudo ip route del {dest_nbma} src {src_nbma} proto 42')
+
+def route_up(interface):
+ dest_addr = os.getenv('NHRP_DESTADDR')
+ dest_prefix = os.getenv('NHRP_DESTPREFIX')
+ next_hop = os.getenv('NHRP_NEXTHOP')
+
+ cmd(f'sudo ip route replace {dest_addr}/{dest_prefix} proto 42 via {next_hop} dev {interface}')
+ cmd('sudo ip route flush cache')
+
+def route_down(interface):
+ dest_addr = os.getenv('NHRP_DESTADDR')
+ dest_prefix = os.getenv('NHRP_DESTPREFIX')
+
+ cmd(f'sudo ip route del {dest_addr}/{dest_prefix} proto 42')
+ cmd('sudo ip route flush cache')
+
+if __name__ == '__main__':
+ action = sys.argv[1]
+ interface = os.getenv('NHRP_INTERFACE')
+ dmvpn_type, profile_name = parse_type_ipsec(interface)
+
+ dmvpn_conn = None
+
+ if profile_name:
+ dmvpn_conn = f'dmvpn-{profile_name}-{interface}'
+
+ if action == 'interface-up':
+ iface_up(interface)
+ elif action == 'peer-register':
+ pass
+ elif action == 'peer-up':
+ peer_up(dmvpn_type, dmvpn_conn)
+ elif action == 'peer-down':
+ peer_down(dmvpn_type, dmvpn_conn)
+ elif action == 'route-up':
+ route_up(interface)
+ elif action == 'route-down':
+ route_down(interface)
diff --git a/src/etc/systemd/system/conntrackd.service.d/override.conf b/src/etc/systemd/system/conntrackd.service.d/override.conf
new file mode 100644
index 000000000..eb611e0d9
--- /dev/null
+++ b/src/etc/systemd/system/conntrackd.service.d/override.conf
@@ -0,0 +1,8 @@
+[Unit]
+After=
+After=vyos-router.service
+ConditionPathExists=/run/conntrackd/conntrackd.conf
+
+[Service]
+ExecStart=
+ExecStart=/usr/sbin/conntrackd -C /run/conntrackd/conntrackd.conf
diff --git a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
index dc751c45c..ec33906ba 100755
--- a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
+++ b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -15,48 +15,47 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
-import syslog as sl
+import syslog
from vyos.config import Config
from vyos import ConfigError
from vyos.util import run
-
def get_config():
c = Config()
interfaces = dict()
for intf in c.list_effective_nodes('interfaces ethernet'):
# skip interfaces that are disabled or is configured for dhcp
- check_disable = "interfaces ethernet {} disable".format(intf)
- check_dhcp = "interfaces ethernet {} address dhcp".format(intf)
+ check_disable = f'interfaces ethernet {intf} disable'
+ check_dhcp = f'interfaces ethernet {intf} address dhcp'
if c.exists_effective(check_disable):
continue
# get addresses configured on the interface
intf_addresses = c.return_effective_values(
- "interfaces ethernet {} address".format(intf)
- )
+ f'interfaces ethernet {intf} address')
interfaces[intf] = [addr.strip("'") for addr in intf_addresses]
return interfaces
-
def apply(config):
+ syslog.openlog(ident='ether-resume', logoption=syslog.LOG_PID,
+ facility=syslog.LOG_INFO)
+
for intf, addresses in config.items():
# bring the interface up
- cmd = ["ip", "link", "set", "dev", intf, "up"]
- sl.syslog(sl.LOG_NOTICE, " ".join(cmd))
+ cmd = f'ip link set dev {intf} up'
+ syslog.syslog(cmd)
run(cmd)
# add configured addresses to interface
for addr in addresses:
- if addr == "dhcp":
- cmd = ["dhclient", intf]
+ if addr == 'dhcp':
+ cmd = ['dhclient', intf]
else:
- cmd = ["ip", "address", "add", addr, "dev", intf]
- sl.syslog(sl.LOG_NOTICE, " ".join(cmd))
+ cmd = f'ip address add {addr} dev {intf}'
+ syslog.syslog(cmd)
run(cmd)
-
if __name__ == '__main__':
try:
config = get_config()