summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/mergifyio_backport.yml2
-rw-r--r--.github/workflows/pull-request-labels.yml4
-rw-r--r--data/templates/ipsec/swanctl/remote_access.j22
-rw-r--r--data/templates/load-balancing/haproxy.cfg.j212
-rw-r--r--interface-definitions/include/accel-ppp/radius-additions.xml.i2
-rw-r--r--interface-definitions/include/haproxy/tcp-request.xml.i22
-rw-r--r--interface-definitions/load-balancing_reverse-proxy.xml.in1
-rw-r--r--interface-definitions/vpn_ipsec.xml.in20
-rw-r--r--python/vyos/utils/convert.py23
-rwxr-xr-xsmoketest/scripts/cli/test_load-balancing_reverse-proxy.py113
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_ipsec.py5
-rw-r--r--src/etc/rsyslog.conf30
-rwxr-xr-xsrc/helpers/vyos-vrrp-conntracksync.sh4
-rwxr-xr-xsrc/op_mode/connect_disconnect.py6
-rwxr-xr-xsrc/op_mode/image_installer.py11
-rwxr-xr-xsrc/op_mode/uptime.py2
16 files changed, 191 insertions, 68 deletions
diff --git a/.github/workflows/mergifyio_backport.yml b/.github/workflows/mergifyio_backport.yml
index f1f4312c4..d9f863d9a 100644
--- a/.github/workflows/mergifyio_backport.yml
+++ b/.github/workflows/mergifyio_backport.yml
@@ -13,7 +13,7 @@ jobs:
id: regex-match
with:
text: ${{ github.event.comment.body }}
- regex: '[Mm]ergifyio backport '
+ regex: '@[Mm][Ee][Rr][Gg][Ii][Ff][Yy][Ii][Oo] backport '
- uses: actions-ecosystem/action-add-labels@v1
if: ${{ steps.regex-match.outputs.match != '' }}
diff --git a/.github/workflows/pull-request-labels.yml b/.github/workflows/pull-request-labels.yml
index 3398af5b0..43856beaa 100644
--- a/.github/workflows/pull-request-labels.yml
+++ b/.github/workflows/pull-request-labels.yml
@@ -12,9 +12,9 @@ on:
jobs:
add-pr-label:
name: Add PR Labels
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- - uses: actions/labeler@v5.0.0
+ - uses: actions/labeler@v5
diff --git a/data/templates/ipsec/swanctl/remote_access.j2 b/data/templates/ipsec/swanctl/remote_access.j2
index adfa32bde..6bced88c7 100644
--- a/data/templates/ipsec/swanctl/remote_access.j2
+++ b/data/templates/ipsec/swanctl/remote_access.j2
@@ -33,7 +33,7 @@
auth = pubkey
{% elif rw_conf.authentication.client_mode.startswith("eap") %}
auth = {{ rw_conf.authentication.client_mode }}
- eap_id = %any
+ eap_id = {{ '%any' if rw_conf.authentication.eap_id == 'any' else rw_conf.authentication.eap_id }}
{% endif %}
{% if rw_conf.authentication.client_mode is vyos_defined('eap-tls') or rw_conf.authentication.client_mode is vyos_defined('x509') %}
{# pass all configured CAs as filenames, separated by commas #}
diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2
index dd93afba5..e8622ba7b 100644
--- a/data/templates/load-balancing/haproxy.cfg.j2
+++ b/data/templates/load-balancing/haproxy.cfg.j2
@@ -69,6 +69,18 @@ frontend {{ front }}
{% endif %}
{% if front_config.mode is vyos_defined %}
mode {{ front_config.mode }}
+{% if front_config.tcp_request.inspect_delay is vyos_defined %}
+ tcp-request inspect-delay {{ front_config.tcp_request.inspect_delay }}
+{% endif %}
+{# add tcp-request related directive if ssl is configed #}
+{% if front_config.mode is vyos_defined('tcp') and front_config.rule is vyos_defined %}
+{% for rule, rule_config in front_config.rule.items() %}
+{% if rule_config.ssl is vyos_defined %}
+ tcp-request content accept if { req_ssl_hello_type 1 }
+{% break %}
+{% endif %}
+{% endfor %}
+{% endif %}
{% endif %}
{% if front_config.rule is vyos_defined %}
{% for rule, rule_config in front_config.rule.items() %}
diff --git a/interface-definitions/include/accel-ppp/radius-additions.xml.i b/interface-definitions/include/accel-ppp/radius-additions.xml.i
index cdd0bf300..3c2eb09eb 100644
--- a/interface-definitions/include/accel-ppp/radius-additions.xml.i
+++ b/interface-definitions/include/accel-ppp/radius-additions.xml.i
@@ -122,7 +122,7 @@
</constraint>
<valueHelp>
<format>ipv4</format>
- <description>IPv4 address for aynamic authorization server</description>
+ <description>IPv4 address for dynamic authorization server</description>
</valueHelp>
</properties>
</leafNode>
diff --git a/interface-definitions/include/haproxy/tcp-request.xml.i b/interface-definitions/include/haproxy/tcp-request.xml.i
new file mode 100644
index 000000000..3d60bd8ad
--- /dev/null
+++ b/interface-definitions/include/haproxy/tcp-request.xml.i
@@ -0,0 +1,22 @@
+<!-- include start from haproxy/tcp-request.xml.i -->
+<node name="tcp-request">
+ <properties>
+ <help>TCP request directive</help>
+ </properties>
+ <children>
+ <leafNode name="inspect-delay">
+ <properties>
+ <help>Set the maximum allowed time to wait for data during content inspection</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>The timeout value specified in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ <constraintErrorMessage>The timeout value must be in range 1 to 65535 milliseconds</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/load-balancing_reverse-proxy.xml.in b/interface-definitions/load-balancing_reverse-proxy.xml.in
index eb01580da..6a3b3cef1 100644
--- a/interface-definitions/load-balancing_reverse-proxy.xml.in
+++ b/interface-definitions/load-balancing_reverse-proxy.xml.in
@@ -38,6 +38,7 @@
#include <include/haproxy/mode.xml.i>
#include <include/port-number.xml.i>
#include <include/haproxy/rule-frontend.xml.i>
+ #include <include/haproxy/tcp-request.xml.i>
<leafNode name="redirect-http-to-https">
<properties>
<help>Redirect HTTP to HTTPS</help>
diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in
index 833019d68..7f425d982 100644
--- a/interface-definitions/vpn_ipsec.xml.in
+++ b/interface-definitions/vpn_ipsec.xml.in
@@ -768,6 +768,26 @@
<children>
#include <include/ipsec/authentication-id.xml.i>
#include <include/ipsec/authentication-x509.xml.i>
+ <leafNode name="eap-id">
+ <properties>
+ <help>Remote EAP ID for client authentication</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Remote EAP ID for client authentication</description>
+ </valueHelp>
+ <completionHelp>
+ <list>any</list>
+ </completionHelp>
+ <valueHelp>
+ <format>any</format>
+ <description>Allow any EAP ID</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:ascii:]]{1,64}</regex>
+ </constraint>
+ </properties>
+ <defaultValue>any</defaultValue>
+ </leafNode>
<leafNode name="client-mode">
<properties>
<help>Client authentication mode</help>
diff --git a/python/vyos/utils/convert.py b/python/vyos/utils/convert.py
index c02f0071e..41e65081f 100644
--- a/python/vyos/utils/convert.py
+++ b/python/vyos/utils/convert.py
@@ -1,4 +1,4 @@
-# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -19,38 +19,43 @@ def seconds_to_human(s, separator=""):
"""
s = int(s)
+ year = 60 * 60 * 24 * 365.25
week = 60 * 60 * 24 * 7
day = 60 * 60 * 24
hour = 60 * 60
- remainder = 0
- result = ""
+ result = []
+
+ years = s // year
+ if years > 0:
+ result.append(f'{int(years)}y')
+ s = int(s % year)
weeks = s // week
if weeks > 0:
- result = "{0}w".format(weeks)
+ result.append(f'{weeks}w')
s = s % week
days = s // day
if days > 0:
- result = "{0}{1}{2}d".format(result, separator, days)
+ result.append(f'{days}d')
s = s % day
hours = s // hour
if hours > 0:
- result = "{0}{1}{2}h".format(result, separator, hours)
+ result.append(f'{hours}h')
s = s % hour
minutes = s // 60
if minutes > 0:
- result = "{0}{1}{2}m".format(result, separator, minutes)
+ result.append(f'{minutes}m')
s = s % 60
seconds = s
if seconds > 0:
- result = "{0}{1}{2}s".format(result, separator, seconds)
+ result.append(f'{seconds}s')
- return result
+ return separator.join(result)
def bytes_to_human(bytes, initial_exponent=0, precision=2,
int_below_exponent=0):
diff --git a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py
index 737c07401..f9f163782 100755
--- a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py
+++ b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py
@@ -299,39 +299,86 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
def test_05_lb_reverse_proxy_backend_http_check(self):
- # Setup base
- self.base_config()
-
- # Set http-check
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'method', 'get'])
- self.cli_commit()
-
- # Test http-check
- config = read_file(HAPROXY_CONF)
- self.assertIn('option httpchk', config)
- self.assertIn('http-check send meth GET', config)
-
- # Set http-check with uri and status
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'uri', '/health'])
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
- self.cli_commit()
-
- # Test http-check with uri and status
- config = read_file(HAPROXY_CONF)
- self.assertIn('option httpchk', config)
- self.assertIn('http-check send meth GET uri /health', config)
- self.assertIn('http-check expect status 200', config)
-
- # Set http-check with string
- self.cli_delete(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
- self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'string', 'success'])
- self.cli_commit()
-
- # Test http-check with string
- config = read_file(HAPROXY_CONF)
- self.assertIn('option httpchk', config)
- self.assertIn('http-check send meth GET uri /health', config)
- self.assertIn('http-check expect string success', config)
+ # Setup base
+ self.base_config()
+
+ # Set http-check
+ self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'method', 'get'])
+ self.cli_commit()
+
+ # Test http-check
+ config = read_file(HAPROXY_CONF)
+ self.assertIn('option httpchk', config)
+ self.assertIn('http-check send meth GET', config)
+
+ # Set http-check with uri and status
+ self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'uri', '/health'])
+ self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
+ self.cli_commit()
+
+ # Test http-check with uri and status
+ config = read_file(HAPROXY_CONF)
+ self.assertIn('option httpchk', config)
+ self.assertIn('http-check send meth GET uri /health', config)
+ self.assertIn('http-check expect status 200', config)
+
+ # Set http-check with string
+ self.cli_delete(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200'])
+ self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'string', 'success'])
+ self.cli_commit()
+
+ # Test http-check with string
+ config = read_file(HAPROXY_CONF)
+ self.assertIn('option httpchk', config)
+ self.assertIn('http-check send meth GET uri /health', config)
+ self.assertIn('http-check expect string success', config)
+
+ def test_06_lb_reverse_proxy_tcp_mode(self):
+ frontend = 'tcp_8443'
+ mode = 'tcp'
+ front_port = '8433'
+ tcp_request_delay = "5000"
+ rule_thirty = '30'
+ domain_bk = 'n6.example.com'
+ ssl_opt = "req-ssl-sni"
+ bk_name = 'bk-03'
+ bk_server = '192.0.2.11'
+ bk_server_port = '9090'
+
+ back_base = base_path + ['backend']
+
+ self.cli_set(base_path + ['service', frontend, 'mode', mode])
+ self.cli_set(base_path + ['service', frontend, 'port', front_port])
+ self.cli_set(base_path + ['service', frontend, 'tcp-request', 'inspect-delay', tcp_request_delay])
+
+ self.cli_set(base_path + ['service', frontend, 'rule', rule_thirty, 'domain-name', domain_bk])
+ self.cli_set(base_path + ['service', frontend, 'rule', rule_thirty, 'ssl', ssl_opt])
+ self.cli_set(base_path + ['service', frontend, 'rule', rule_thirty, 'set', 'backend', bk_name])
+
+ self.cli_set(back_base + [bk_name, 'mode', mode])
+ self.cli_set(back_base + [bk_name, 'server', bk_name, 'address', bk_server])
+ self.cli_set(back_base + [bk_name, 'server', bk_name, 'port', bk_server_port])
+
+ # commit changes
+ self.cli_commit()
+
+ config = read_file(HAPROXY_CONF)
+
+ # Frontend
+ self.assertIn(f'frontend {frontend}', config)
+ self.assertIn(f'bind :::{front_port} v4v6', config)
+ self.assertIn(f'mode {mode}', config)
+
+ self.assertIn(f'tcp-request inspect-delay {tcp_request_delay}', config)
+ self.assertIn(f"tcp-request content accept if {{ req_ssl_hello_type 1 }}", config)
+ self.assertIn(f'acl {rule_thirty} req_ssl_sni -i {domain_bk}', config)
+ self.assertIn(f'use_backend {bk_name} if {rule_thirty}', config)
+
+ # Backend
+ self.assertIn(f'backend {bk_name}', config)
+ self.assertIn(f'balance roundrobin', config)
+ self.assertIn(f'mode {mode}', config)
+ self.assertIn(f'server {bk_name} {bk_server}:{bk_server_port}', config)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py
index 145b5990e..27356d70e 100755
--- a/smoketest/scripts/cli/test_vpn_ipsec.py
+++ b/smoketest/scripts/cli/test_vpn_ipsec.py
@@ -782,6 +782,11 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.assertTrue(os.path.exists(os.path.join(CA_PATH, f'{ca_name}.pem')))
self.assertTrue(os.path.exists(os.path.join(CERT_PATH, f'{peer_name}.pem')))
+ # Test setting of custom EAP ID
+ self.cli_set(base_path + ['remote-access', 'connection', conn_name, 'authentication', 'eap-id', 'eap-user@vyos.net'])
+ self.cli_commit()
+ self.assertIn(r'eap_id = eap-user@vyos.net', read_file(swanctl_file))
+
self.tearDownPKI()
def test_remote_access_x509(self):
diff --git a/src/etc/rsyslog.conf b/src/etc/rsyslog.conf
index 9781f0835..b3f41acb6 100644
--- a/src/etc/rsyslog.conf
+++ b/src/etc/rsyslog.conf
@@ -15,21 +15,6 @@ $KLogPath /proc/kmsg
#### GLOBAL DIRECTIVES ####
###########################
-# The lines below cause all listed daemons/processes to be logged into
-# /var/log/auth.log, then drops the message so it does not also go to the
-# regular syslog so that messages are not duplicated
-
-$outchannel auth_log,/var/log/auth.log
-if $programname == 'CRON' or
- $programname == 'sudo' or
- $programname == 'su'
- then :omfile:$auth_log
-
-if $programname == 'CRON' or
- $programname == 'sudo' or
- $programname == 'su'
- then stop
-
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
# A modern-style logfile format similar to TraditionalFileFormat, buth with high-precision timestamps and timezone information
@@ -60,6 +45,21 @@ $Umask 0022
#
$IncludeConfig /etc/rsyslog.d/*.conf
+# The lines below cause all listed daemons/processes to be logged into
+# /var/log/auth.log, then drops the message so it does not also go to the
+# regular syslog so that messages are not duplicated
+
+$outchannel auth_log,/var/log/auth.log
+if $programname == 'CRON' or
+ $programname == 'sudo' or
+ $programname == 'su'
+ then :omfile:$auth_log
+
+if $programname == 'CRON' or
+ $programname == 'sudo' or
+ $programname == 'su'
+ then stop
+
###############
#### RULES ####
###############
diff --git a/src/helpers/vyos-vrrp-conntracksync.sh b/src/helpers/vyos-vrrp-conntracksync.sh
index 0cc718938..90fa77f23 100755
--- a/src/helpers/vyos-vrrp-conntracksync.sh
+++ b/src/helpers/vyos-vrrp-conntracksync.sh
@@ -25,7 +25,7 @@ LOGCMD="logger -t $TAG -p $FACILITY.$LEVEL"
VRRP_GRP="VRRP sync-group [$2]"
FAILOVER_STATE="/var/run/vyatta-conntrackd-failover-state"
-$LOGCMD "vyatta-vrrp-conntracksync invoked at `date`"
+$LOGCMD "vyos-vrrp-conntracksync invoked at `date`"
if ! systemctl is-active --quiet conntrackd.service; then
echo "conntrackd service not running"
@@ -148,7 +148,7 @@ case "$1" in
*)
echo UNKNOWN at `date` > $FAILOVER_STATE
$LOGCMD "ERROR: `uname -n` unknown state transition for $VRRP_GRP"
- echo "Usage: vyatta-vrrp-conntracksync.sh {master|backup|fault}"
+ echo "Usage: vyos-vrrp-conntracksync.sh {master|backup|fault}"
exit 1
;;
esac
diff --git a/src/op_mode/connect_disconnect.py b/src/op_mode/connect_disconnect.py
index bd02dc6ea..373f9e953 100755
--- a/src/op_mode/connect_disconnect.py
+++ b/src/op_mode/connect_disconnect.py
@@ -48,7 +48,7 @@ def connect(interface):
if os.path.isdir(f'/sys/class/net/{interface}'):
print(f'Interface {interface}: already connected!')
elif check_ppp_running(interface):
- print(f'Interface {interface}: connection is beeing established!')
+ print(f'Interface {interface}: connection is being established!')
else:
print(f'Interface {interface}: connecting...')
call(f'systemctl restart ppp@{interface}.service')
@@ -58,7 +58,7 @@ def connect(interface):
else:
call(f'VYOS_TAGNODE_VALUE={interface} /usr/libexec/vyos/conf_mode/interfaces_wwan.py')
else:
- print(f'Unknown interface {interface}, can not connect. Aborting!')
+ print(f'Unknown interface {interface}, cannot connect. Aborting!')
# Reaply QoS configuration
config = ConfigTreeQuery()
@@ -90,7 +90,7 @@ def disconnect(interface):
modem = interface.lstrip('wwan')
call(f'mmcli --modem {modem} --simple-disconnect', stdout=DEVNULL)
else:
- print(f'Unknown interface {interface}, can not disconnect. Aborting!')
+ print(f'Unknown interface {interface}, cannot disconnect. Aborting!')
def main():
parser = argparse.ArgumentParser()
diff --git a/src/op_mode/image_installer.py b/src/op_mode/image_installer.py
index b1311b6f9..ba0e3b6db 100755
--- a/src/op_mode/image_installer.py
+++ b/src/op_mode/image_installer.py
@@ -26,6 +26,7 @@ from os import environ
from typing import Union
from urllib.parse import urlparse
from passlib.hosts import linux_context
+from errno import ENOSPC
from psutil import disk_partitions
@@ -939,6 +940,16 @@ def add_image(image_path: str, vrf: str = None, username: str = '',
if set_as_default:
grub.set_default(image_name, root_dir)
+ except OSError as e:
+ # if no space error, remove image dir and cleanup
+ if e.errno == ENOSPC:
+ cleanup(mounts=[str(iso_path)],
+ remove_items=[f'{root_dir}/boot/{image_name}'])
+ else:
+ # unmount an ISO and cleanup
+ cleanup([str(iso_path)])
+ exit(f'Error: {e}')
+
except Exception as err:
# unmount an ISO and cleanup
cleanup([str(iso_path)])
diff --git a/src/op_mode/uptime.py b/src/op_mode/uptime.py
index d6adf6f4d..059a4c3f6 100755
--- a/src/op_mode/uptime.py
+++ b/src/op_mode/uptime.py
@@ -49,7 +49,7 @@ def _get_raw_data():
res = {}
res["uptime_seconds"] = _get_uptime_seconds()
- res["uptime"] = seconds_to_human(_get_uptime_seconds())
+ res["uptime"] = seconds_to_human(_get_uptime_seconds(), separator=' ')
res["load_average"] = _get_load_averages()
return res