diff --git a/bubble-server/src/main/resources/ansible/roles/algo/templates/install_algo.sh.j2 b/bubble-server/src/main/resources/ansible/roles/algo/templates/install_algo.sh.j2 index 086de678..0b98585a 100644 --- a/bubble-server/src/main/resources/ansible/roles/algo/templates/install_algo.sh.j2 +++ b/bubble-server/src/main/resources/ansible/roles/algo/templates/install_algo.sh.j2 @@ -43,6 +43,34 @@ CONFIGS_BACKUP=/home/bubble/.BUBBLE_ALGO_CONFIGS.tgz cd ${ALGO_BASE} && tar czf ${CONFIGS_BACKUP} configs && chgrp bubble ${CONFIGS_BACKUP} && chmod 660 ${CONFIGS_BACKUP} || die "Error backing up algo configs" cd /home/bubble && tar xzf ${CONFIGS_BACKUP} && chgrp -R bubble configs && chown -R bubble configs && chmod 500 configs || die "Error unpacking algo configs to bubble home" +# Write VPN subnets to mitmproxy +WG_IP4=$(cat ${ALGO_BASE}/config.cfg | grep wireguard_network_ipv4 | grep -v '^#' | awk -F': ' '{print $2}' | tr -d ' ') +if [[ -z ${WG_IP4} ]] ; then + die "wireguard_network_ipv4 not found in ${ALGO_BASE}/config.cfg" +fi +WG_IP6=$(cat ${ALGO_BASE}/config.cfg | grep wireguard_network_ipv6 | grep -v '^#' | awk -F': ' '{print $2}' | tr -d ' ') +if [[ -z ${WG_IP6} ]] ; then + die "wireguard_network_ipv6 not found in ${ALGO_BASE}/config.cfg" +fi + +VPN_IP4_PY=/home/mitmproxy/mitmproxy/bubble_vpn4.py +if [[ ! -f ${VPN_IP4_PY} || $(cat ${VPN_IP4_PY} | grep -c ${WG_IP4}) -eq 0 ]] ; then + echo " +wireguard_network_ipv4 = '${WG_IP4}' +" > ${VPN_IP4_PY} || die "Error writing VPN subnet to ${VPN_IP4_PY}" + chown mitmproxy.mitmproxy ${VPN_IP4_PY} || die "Error setting owner of ${VPN_IP4_PY} to mitmproxy" + chmod 500 ${VPN_IP4_PY} || die "Error setting permissions on ${VPN_PY}" +fi + +VPN_IP6_PY=/home/mitmproxy/mitmproxy/bubble_vpn6.py +if [[ ! -f ${VPN_IP6_PY} || $(cat ${VPN_IP6_PY} | grep -c ${WG_IP6}) -eq 0 ]] ; then + echo " +wireguard_network_ipv6 = '${WG_IP6}' +" > ${VPN_IP6_PY} || die "Error writing VPN subnet to ${VPN_IP6_PY}" + chown mitmproxy.mitmproxy ${VPN_IP6_PY} || die "Error setting owner of ${VPN_IP6_PY} to mitmproxy" + chmod 500 ${VPN_IP6_PY} || die "Error setting permissions on ${VPN_IP6_PY}" +fi + # Restart algo_refresh_users_monitor and wg_monitor_connections supervisorctl reload && sleep 3s && supervisorctl restart algo_refresh_users_monitor && supervisorctl restart wg_monitor_connections diff --git a/bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_conn_check.py b/bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_conn_check.py index 3916849a..a806469e 100644 --- a/bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_conn_check.py +++ b/bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_conn_check.py @@ -29,6 +29,9 @@ from mitmproxy.net import tls as net_tls from bubble_api import bubble_log, bubble_conn_check, bubble_activity_log, REDIS, redis_set from bubble_config import bubble_sage_host, bubble_sage_ip4, bubble_sage_ip6, cert_validation_host +from bubble_vpn4 import wireguard_network_ipv4 +from bubble_vpn6 import wireguard_network_ipv6 +from netaddr import IPAddress, IPNetwork import json import subprocess import traceback @@ -49,6 +52,9 @@ SEC_OFF = 'disabled' local_ips = None +VPN_IP4_CIDR = IPNetwork(wireguard_network_ipv4) +VPN_IP6_CIDR = IPNetwork(wireguard_network_ipv6) + def get_device_security_level(client_addr): level = REDIS.get(REDIS_KEY_DEVICE_SECURITY_LEVEL_PREFIX+client_addr) @@ -70,6 +76,11 @@ def is_sage_request(ip, fqdns): return ip == bubble_sage_ip4 or ip == bubble_sage_ip6 or bubble_sage_host in fqdns +def is_not_from_vpn(client_addr): + ip = IPAddress(client_addr) + return ip not in VPN_IP4_CIDR and ip not in VPN_IP6_CIDR + + def conn_check_cache_prefix(client_addr, server_addr): return REDIS_CONN_CHECK_PREFIX + client_addr + '_' + server_addr @@ -203,6 +214,11 @@ def next_layer(next_layer): bubble_log('next_layer: enabling passthru for SAGE server='+server_addr+' regardless of security_level='+security_level+' for client='+client_addr) check = FORCE_PASSTHRU + elif is_not_from_vpn(client_addr): + bubble_log('next_layer: enabling block for non-VPN client='+client_addr+', fqdns='+str(fqdns)) + bubble_activity_log(client_addr, server_addr, 'conn_block_non_vpn', fqdns) + next_layer.__class__ = TlsBlock + elif security_level == SEC_OFF or security_level == SEC_BASIC: bubble_log('next_layer: enabling passthru for server='+server_addr+' because security_level='+security_level+' for client='+client_addr) check = FORCE_PASSTHRU diff --git a/bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml b/bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml index fcee8a4c..3e9baab2 100644 --- a/bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml +++ b/bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml @@ -40,7 +40,7 @@ get_url: url: https://github.com/getbubblenow/bubble-dist/raw/master/mitmproxy/mitmproxy.zip dest: /tmp/mitmproxy.zip - checksum: sha256:1466520af16761b22f4802506cc2d81defdbe759e83bc626aec6a27a4376527a + checksum: sha256:1f6fef51e26c6496955979a84d1c0bd797521832fde01a4de79c7cfe25c3da71 - name: Unzip mitmproxy.zip unarchive: