summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-07-20 20:33:54 +0200
committerGitHub <noreply@github.com>2021-07-20 20:33:54 +0200
commit4d55afded46a07c761a724989e0e66fe88d705c7 (patch)
tree5c9cae9c04121dd082c0a7a3e6d262df27c86489 /src
parent4ff379d18a750314fda2b2fec5a1e285bd92f15c (diff)
parentbfadd6dfb5969f231097353a76ada3b839964a19 (diff)
downloadvyos-1x-4d55afded46a07c761a724989e0e66fe88d705c7.tar.gz
vyos-1x-4d55afded46a07c761a724989e0e66fe88d705c7.zip
Merge pull request #931 from sarthurdev/pki_eapol
pki: eapol: T3642: Migrate EAPoL to use PKI configuration
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py31
-rwxr-xr-xsrc/migration-scripts/interfaces/22-to-23134
2 files changed, 144 insertions, 21 deletions
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index 378f400b8..78c24952b 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -32,6 +32,8 @@ from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ethtool import Ethtool
from vyos.ifconfig import EthernetIf
+from vyos.pki import wrap_certificate
+from vyos.pki import wrap_private_key
from vyos.template import render
from vyos.util import call
from vyos.util import dict_search
@@ -40,6 +42,7 @@ from vyos import airbag
airbag.enable()
# XXX: wpa_supplicant works on the source interface
+cfg_dir = '/run/wpa_supplicant'
wpa_suppl_conf = '/run/wpa_supplicant/{ifname}.conf'
def get_config(config=None):
@@ -52,8 +55,15 @@ def get_config(config=None):
else:
conf = Config()
base = ['interfaces', 'ethernet']
+
+ tmp_pki = conf.get_config_dict(['pki'], key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+
ethernet = get_interface_dict(conf, base)
+ if 'deleted' not in ethernet:
+ ethernet['pki'] = tmp_pki
+
return ethernet
def verify(ethernet):
@@ -126,6 +136,27 @@ def generate(ethernet):
if 'eapol' in ethernet:
render(wpa_suppl_conf.format(**ethernet),
'ethernet/wpa_supplicant.conf.tmpl', ethernet)
+
+ ifname = ethernet['ifname']
+ cert_file_path = os.path.join(cfg_dir, f'{ifname}_cert.pem')
+ cert_key_path = os.path.join(cfg_dir, f'{ifname}_cert.key')
+
+ cert_name = ethernet['eapol']['certificate']
+ pki_cert = ethernet['pki']['certificate'][cert_name]
+
+ with open(cert_file_path, 'w') as f:
+ f.write(wrap_certificate(pki_cert['certificate']))
+
+ with open(cert_key_path, 'w') as f:
+ f.write(wrap_private_key(pki_cert['private']['key']))
+
+ if 'ca_certificate' in ethernet['eapol']:
+ ca_cert_file_path = os.path.join(cfg_dir, f'{ifname}_ca.pem')
+ ca_cert_name = ethernet['eapol']['ca_certificate']
+ pki_ca_cert = ethernet['pki']['ca'][cert_name]
+
+ with open(ca_cert_file_path, 'w') as f:
+ f.write(wrap_certificate(pki_ca_cert['certificate']))
else:
# delete configuration on interface removal
if os.path.isfile(wpa_suppl_conf.format(**ethernet)):
diff --git a/src/migration-scripts/interfaces/22-to-23 b/src/migration-scripts/interfaces/22-to-23
index c52a26908..3fd5998a0 100755
--- a/src/migration-scripts/interfaces/22-to-23
+++ b/src/migration-scripts/interfaces/22-to-23
@@ -14,30 +14,35 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# A VTI interface also requires an IPSec configuration - VyOS 1.2 supported
-# having a VTI interface in the CLI but no IPSec configuration - drop VTI
-# configuration if this is the case for VyOS 1.4
+# Migrate Wireguard to store keys in CLI
+# Migrate EAPoL to PKI configuration
import os
import sys
from vyos.configtree import ConfigTree
+from vyos.pki import load_certificate
+from vyos.pki import load_private_key
+from vyos.pki import encode_certificate
+from vyos.pki import encode_private_key
-if __name__ == '__main__':
- if (len(sys.argv) < 1):
- print("Must specify file name!")
- sys.exit(1)
+def wrapped_pem_to_config_value(pem):
+ return "".join(pem.strip().split("\n")[1:-1])
- file_name = sys.argv[1]
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
- with open(file_name, 'r') as f:
- config_file = f.read()
+file_name = sys.argv[1]
- config = ConfigTree(config_file)
- base = ['interfaces', 'wireguard']
- if not config.exists(base):
- # Nothing to do
- sys.exit(0)
+with open(file_name, 'r') as f:
+ config_file = f.read()
+config = ConfigTree(config_file)
+
+# Wireguard
+base = ['interfaces', 'wireguard']
+
+if config.exists(base):
for interface in config.list_nodes(base):
private_key_path = base + [interface, 'private-key']
@@ -58,9 +63,96 @@ if __name__ == '__main__':
for peer in config.list_nodes(base + [interface, 'peer']):
config.rename(base + [interface, 'peer', peer, 'pubkey'], 'public-key')
- try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
- except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- sys.exit(1)
+# Ethernet EAPoL
+base = ['interfaces', 'ethernet']
+
+if config.exists(base):
+ AUTH_DIR = '/config/auth'
+ pki_base = ['pki']
+
+ for interface in config.list_nodes(base):
+ if not config.exists(base + [interface, 'eapol']):
+ continue
+
+ x509_base = base + [interface, 'eapol']
+ pki_name = f'eapol_{interface}'
+
+ if config.exists(x509_base + ['ca-cert-file']):
+ if not config.exists(pki_base + ['ca']):
+ config.set(pki_base + ['ca'])
+ config.set_tag(pki_base + ['ca'])
+
+ cert_file = config.return_value(x509_base + ['ca-cert-file'])
+ cert_path = os.path.join(AUTH_DIR, cert_file)
+ cert = None
+
+ if os.path.isfile(cert_path):
+ if not os.access(cert_path, os.R_OK):
+ run(f'sudo chmod 644 {cert_path}')
+
+ with open(cert_path, 'r') as f:
+ cert_data = f.read()
+ cert = load_certificate(cert_data, wrap_tags=False)
+
+ if cert:
+ cert_pem = encode_certificate(cert)
+ config.set(pki_base + ['ca', pki_name, 'certificate'], value=wrapped_pem_to_config_value(cert_pem))
+ config.set(x509_base + ['ca-certificate'], value=pki_name)
+ else:
+ print(f'Failed to migrate CA certificate on eapol config for interface {interface}')
+
+ config.delete(x509_base + ['ca-cert-file'])
+
+ if config.exists(x509_base + ['cert-file']):
+ if not config.exists(pki_base + ['certificate']):
+ config.set(pki_base + ['certificate'])
+ config.set_tag(pki_base + ['certificate'])
+
+ cert_file = config.return_value(x509_base + ['cert-file'])
+ cert_path = os.path.join(AUTH_DIR, cert_file)
+ cert = None
+
+ if os.path.isfile(cert_path):
+ if not os.access(cert_path, os.R_OK):
+ run(f'sudo chmod 644 {cert_path}')
+
+ with open(cert_path, 'r') as f:
+ cert_data = f.read()
+ cert = load_certificate(cert_data, wrap_tags=False)
+
+ if cert:
+ cert_pem = encode_certificate(cert)
+ config.set(pki_base + ['certificate', pki_name, 'certificate'], value=wrapped_pem_to_config_value(cert_pem))
+ config.set(x509_base + ['certificate'], value=pki_name)
+ else:
+ print(f'Failed to migrate certificate on eapol config for interface {interface}')
+
+ config.delete(x509_base + ['cert-file'])
+
+ if config.exists(x509_base + ['key-file']):
+ key_file = config.return_value(x509_base + ['key-file'])
+ key_path = os.path.join(AUTH_DIR, key_file)
+ key = None
+
+ if os.path.isfile(key_path):
+ if not os.access(key_path, os.R_OK):
+ run(f'sudo chmod 644 {key_path}')
+
+ with open(key_path, 'r') as f:
+ key_data = f.read()
+ key = load_private_key(key_data, passphrase=None, wrap_tags=False)
+
+ if key:
+ key_pem = encode_private_key(key, passphrase=None)
+ config.set(pki_base + ['certificate', pki_name, 'private', 'key'], value=wrapped_pem_to_config_value(key_pem))
+ else:
+ print(f'Failed to migrate private key on eapol config for interface {interface}')
+
+ config.delete(x509_base + ['key-file'])
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)