diff --git a/doc/builder/ap.sh b/doc/builder/ap.sh new file mode 100644 index 0000000..ca6799a --- /dev/null +++ b/doc/builder/ap.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +source common.sh + +uci set certidude.@authority[0].trigger=lan + +cat << \EOF > $OVERLAY/etc/uci-defaults/40-hostname + +MODEL=$(cat /etc/board.json | jsonfilter -e '@["model"]["id"]') + +# Hostname prefix +case $MODEL in + tl-*|archer-*) VENDOR=tplink ;; + cf-*) VENDOR=comfast ;; + *) VENDOR=ap ;; +esac + +# Network interface with relevant MAC address +case $MODEL in + tl-wdr*) NIC=wlan1 ;; + archer-*) NIC=eth1 ;; + cf-e380ac-v2) NIC=eth0 ;; + *) NIC=wlan0 ;; +esac + +HOSTNAME=$VENDOR-$(cat /sys/class/net/$NIC/address | cut -d : -f 4- | sed -e 's/://g') +uci set system.@system[0].hostname=$HOSTNAME +uci set network.lan.hostname=$HOSTNAME + +EOF + +cat << \EOF > $OVERLAY/etc/uci-defaults/50-access-point + +# Remove firewall rules since AP bridges ethernet to wireless anyway +uci delete firewall.@zone[1] +uci delete firewall.@zone[0] +uci delete firewall.@forwarding[0] +for j in $(seq 0 10); do uci delete firewall.@rule[0]; done + +# Remove WAN interface +uci delete network.wan +uci delete network.wan6 + +# Reconfigure DHCP client for bridge over LAN and WAN ports +uci delete network.lan.ipaddr +uci delete network.lan.netmask +uci delete network.lan.ip6assign +uci delete network.globals.ula_prefix +uci delete network.@switch_vlan[1] +uci delete dhcp.@dnsmasq[0].domain +uci set network.lan.proto=dhcp +uci set network.lan.ipv6=0 +uci set network.lan.ifname='eth0' +uci set network.lan.stp=1 + +# Radio ordering differs among models +case $(uci get wireless.radio0.hwmode) in + 11a) uci rename wireless.radio0=radio5ghz;; + 11g) uci rename wireless.radio0=radio2ghz;; +esac +case $(uci get wireless.radio1.hwmode) in + 11a) uci rename wireless.radio1=radio5ghz;; + 11g) uci rename wireless.radio1=radio2ghz;; +esac + +# Reset virtual SSID-s +uci delete wireless.@wifi-iface[1] +uci delete wireless.@wifi-iface[0] + +# Pseudorandomize channel selection, should work with 80MHz on 5GHz band +case $(uci get system.@system[0].hostname | md5sum) in + 1*|2*|3*|4*) uci set wireless.radio2ghz.channel=1; uci set wireless.radio5ghz.channel=36 ;; + 5*|6*|7*|8*) uci set wireless.radio2ghz.channel=5; uci set wireless.radio5ghz.channel=52 ;; + 9*|0*|a*|b*) uci set wireless.radio2ghz.channel=9; uci set wireless.radio5ghz.channel=100 ;; + c*|d*|e*|f*) uci set wireless.radio2ghz.channel=13; uci set wireless.radio5ghz.channel=132 ;; +esac + +# Create bridge for guests +uci set network.guest=interface +uci set network.guest.proto='static' +uci set network.guest.address='0.0.0.0' +uci set network.guest.type='bridge' +uci set network.guest.ifname='eth0.156' # tag id 156 for guest network +uci set network.guest.ipaddr='0.0.0.0' +uci set network.guest.ipv6=0 +uci set network.guest.stp=1 + +# Add VPN interface for IPSec +uci set network.vpn=interface +uci set network.vpn.ifname='ipsec0' +uci set network.vpn.proto='none' + +uci set firewall.vpn=zone +uci set firewall.vpn.name="vpn" +uci set firewall.vpn.input="ACCEPT" +uci set firewall.vpn.forward="ACCEPT" +uci set firewall.vpn.output="ACCEPT" +uci set firewall.vpn.network="vpn" + +# Disable switch tagging and bridge all ports on TP-Link WDR3600/WDR4300 +case $(cat /etc/board.json | jsonfilter -e '@["model"]["id"]') in + tl-wdr*|archer*) + uci set network.@switch[0].enable_vlan=0 + uci set network.@switch_vlan[0].ports='0 1 2 3 4 5 6' + ;; + *) ;; +esac + +EOF + +make -C $BUILD/$BASENAME image FILES=$OVERLAY PROFILE=$PROFILE PACKAGES="luci luci-app-commands \ + openssl-util curl ca-certificates \ + strongswan-mod-kernel-libipsec kmod-tun ip-full strongswan-full \ + htop iftop tcpdump nmap nano -odhcp6c -odhcpd -dnsmasq \ + -luci-app-firewall \ + -pppd -luci-proto-ppp -kmod-ppp -ppp -ppp-mod-pppoe \ + -kmod-ip6tables -ip6tables -luci-proto-ipv6 -kmod-iptunnel6 -kmod-ipsec6" + + diff --git a/doc/builder/common.sh b/doc/builder/common.sh new file mode 100644 index 0000000..cec3ef9 --- /dev/null +++ b/doc/builder/common.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e +set -x +umask 022 + +VERSION=17.01.4 +BASENAME=lede-imagebuilder-$VERSION-ar71xx-generic.Linux-x86_64 +FILENAME=$BASENAME.tar.xz +URL=http://downloads.lede-project.org/releases/$VERSION/targets/ar71xx/generic/$FILENAME + +if [ ! -e $BUILD/$FILENAME ]; then + wget -q $URL -O $BUILD/$FILENAME +fi + +if [ ! -e $BUILD/$BASENAME ]; then + tar xf $BUILD/$FILENAME -C $BUILD +fi + +# Copy CA certificate +AUTHORITY=$(hostname -f) +CERTIDUDE_DIR=/var/lib/certidude/$AUTHORITY + +mkdir -p $OVERLAY/etc/config +mkdir -p $OVERLAY/etc/uci-defaults +mkdir -p $OVERLAY/etc/certidude/authority/$AUTHORITY +cp /var/lib/certidude/$AUTHORITY/ca_cert.pem $OVERLAY/etc/certidude/authority/$AUTHORITY/ + +cat < $OVERLAY/etc/config/certidude + +config authority + option gateway router.k-space.ee + option url http://$AUTHORITY + option trigger wan + option authority_path /etc/certidude/authority/$AUTHORITY/ca_cert.pem + option request_path /etc/certidude/authority/$AUTHORITY/client_req.pem + option certificate_path /etc/certidude/authority/$AUTHORITY/client_cert.pem + option key_path /etc/certidude/authority/$AUTHORITY/client_key.pem + option key_type rsa + option key_length 2048 + +EOF + +cat << EOF > $OVERLAY/etc/uci-defaults/40-disable-ipsec +/etc/init.d/ipsec disable +EOF + + + +cat << EOF > $OVERLAY/etc/ipsec.secrets +: RSA /etc/certidude/authority/$AUTHORITY/client_key.pem +EOF + +cat << EOF > $OVERLAY/etc/ipsec.conf + +config setup + +ca $AUTHORITY + cacert=/etc/certidude/authority/$AUTHORITY/ca_cert.pem + auto=add + +conn router.k-space.ee + right=router.k-space.ee + dpdaction=restart + auto=start + rightsubnet=0.0.0.0/0 + rightid=%any + leftsourceip=%config + keyexchange=ikev2 + closeaction=restart + leftcert=/etc/certidude/authority/$AUTHORITY/client_cert.pem + left=%defaultroute + +EOF + + diff --git a/doc/builder/ipcam.sh b/doc/builder/ipcam.sh new file mode 100644 index 0000000..ed05350 --- /dev/null +++ b/doc/builder/ipcam.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +. common.sh + +cat << \EOF > $OVERLAY/etc/uci-defaults/40-hostname + +HOSTNAME=cam-$(cat /sys/class/net/eth0/address | cut -d : -f 4- | sed -e 's/://g') +uci set system.@system[0].hostname=$HOSTNAME +uci set network.wan.hostname=$HOSTNAME + +EOF + +touch $OVERLAY/etc/config/wireless + +cat << EOF > $OVERLAY/etc/uci-defaults/50-ipcam + +uci delete network.lan +uci delete network.wan6 + +uci set network.vpn=interface +uci set network.vpn.ifname='ipsec0' +uci set network.vpn.proto='none' +uci set firewall.@zone[0].network=vpn +uci delete firewall.@forwarding[0] + +uci set mjpg-streamer.core.enabled=1 +uci set mjpg-streamer.core.quality='' +uci set mjpg-streamer.core.resolution='1280x720' +uci delete mjpg-streamer.core.username +uci delete mjpg-streamer.core.password + +uci certidude.@authority[0].red_led='gl-connect:red:wlan' +uci certidude.@authority[0].green_led='gl-connect:green:lan' + +/etc/init.d/dropbear disable +/etc/init.d/ipsec disable + +EOF + + +make -C $BUILD/$BASENAME image FILES=$OVERLAY PROFILE=$PROFILE PACKAGES="openssl-util curl ca-certificates strongswan-full htop \ + iftop tcpdump nmap nano mtr patch diffutils ipset usbutils luci luci-app-mjpg-streamer kmod-video-uvc \ + pciutils -dnsmasq -odhcpd -odhcp6c -kmod-ath9k picocom strongswan-mod-kernel-libipsec kmod-tun ip-full" diff --git a/doc/builder/mfp.sh b/doc/builder/mfp.sh new file mode 100644 index 0000000..6095be7 --- /dev/null +++ b/doc/builder/mfp.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +. common.sh + +cat << \EOF > $OVERLAY/etc/uci-defaults/40-hostname + +HOSTNAME=mfp-$(cat /sys/class/net/eth0/address | cut -d : -f 4- | sed -e 's/://g') +uci set system.@system[0].hostname=$HOSTNAME +uci set network.wan.hostname=$HOSTNAME + +EOF + +mkdir -p $OVERLAY/etc/config/ +touch $OVERLAY/etc/config/wireless + +cat << EOF > $OVERLAY/etc/uci-defaults/50-mfp + +# Disable rebind protection for DNS +uci set dhcp.@dnsmasq[0].rebind_protection=0 +uci set dhcp.@dnsmasq[0].domain='mfp.lan' +uci delete dhcp.@dnsmasq[0].local + +# Disable bridge for LAN since WiFi is disabled +uci delete network.lan.type +uci set dhcp.lan.limit=1 + +uci set network.vpn=interface +uci set network.vpn.ifname='ipsec0' +uci set network.vpn.proto='none' + +uci set firewall.vpn=zone +uci set firewall.vpn.name="vpn" +uci set firewall.vpn.input="ACCEPT" +uci set firewall.vpn.forward="ACCEPT" +uci set firewall.vpn.output="ACCEPT" +uci set firewall.vpn.network="vpn" + +uci set firewall.lan2vpn=forwarding +uci set firewall.lan2vpn.src='lan' +uci set firewall.lan2vpn.dest='vpn' + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow IPP on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=631 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=tcp + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow HTTP on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=80 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=tcp + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow HTTPS on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=443 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=tcp + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow JetDirect on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=9100 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=tcp +uci set firewall.@redirect[-1].enabled=0 + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow SNMP on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=161 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=udp +uci set firewall.@redirect[-1].enabled=0 + +uci add firewall redirect +uci set firewall.@redirect[-1].name="Allow LPD on MFP" +uci set firewall.@redirect[-1].src=vpn +uci set firewall.@redirect[-1].src_dport=515 +uci set firewall.@redirect[-1].dest=lan +uci set firewall.@redirect[-1].dest_ip=192.168.1.100 +uci set firewall.@redirect[-1].target=DNAT +uci set firewall.@redirect[-1].proto=tcp +uci set firewall.@redirect[-1].enabled=0 + +uci set uhttpd.main.listen_http=0.0.0.0:8080 + +/etc/init.d/dropbear disable + +EOF + +make -C $BUILD/$BASENAME image FILES=$OVERLAY PROFILE=$PROFILE PACKAGES="openssl-util curl ca-certificates htop \ + iftop tcpdump nmap nano mtr patch diffutils ipset usbutils luci \ + strongswan-mod-kernel-libipsec kmod-tun ip-full strongswan-full \ + pciutils -odhcpd -odhcp6c -kmod-ath9k picocom libustream-openssl kmod-crypto-gcm" + + diff --git a/doc/overlay/etc/hotplug.d/iface/50-certidude b/doc/overlay/etc/hotplug.d/iface/50-certidude deleted file mode 100755 index 0103a43..0000000 --- a/doc/overlay/etc/hotplug.d/iface/50-certidude +++ /dev/null @@ -1,178 +0,0 @@ -#!/bin/sh - -# To paste, press Ctrl-D to finish: cat > /etc/hotplug.d/iface/50-certidude -# To test: ACTION=ifup INTERFACE=wan sh /etc/hotplug.d/iface/50-certidude - -# TODO: renewal - -AUTHORITY=certidude.@authority[0] - -[ $ACTION == "ifup" ] || exit 0 -[ $INTERFACE == "$(uci get $AUTHORITY.trigger)" ] || exit 0 - -# TODO: iterate over all authorities - -URL=$(uci get $AUTHORITY.url) -GATEWAY=$(uci get $AUTHORITY.gateway) - -COMMON_NAME=$(uci get $AUTHORITY.common_name) -if [ $? -ne 0 ]; then - COMMON_NAME=$(uci get system.@system[0].hostname) -fi - -KEY_PATH=$(uci get $AUTHORITY.key_path) -KEY_TYPE=$(uci get $AUTHORITY.key_type) -KEY_LENGTH=$(uci get $AUTHORITY.key_length) - -CERTIFICATE_PATH=$(uci get $AUTHORITY.certificate_path) -REQUEST_PATH=$(uci get $AUTHORITY.request_path) -AUTHORITY_PATH=$(uci get $AUTHORITY.authority_path) - -RED_LED=/sys/class/leds/$(uci get $AUTHORITY.red_led) -GREEN_LED=/sys/class/leds/$(uci get $AUTHORITY.green_led) - -NTP_SERVERS=$(uci get system.ntp.server) - -logger -t certidude -s "Fetching time from NTP servers: $NTP_SERVERS" -ntpd -q -n -d -p $NTP_SERVERS - -logger -t certidude -s "Time is now: $(date)" - -# If certificate file is there assume everything's set up -if [ -f $CERTIFICATE_PATH ]; then - SERIAL=$(openssl x509 -in $CERTIFICATE_PATH -noout -serial | cut -d "=" -f 2 | tr [A-F] [a-f]) - logger -t certidude -s "Certificate with serial $SERIAL already exists in $CERTIFICATE_PATH, attempting to bring up VPN tunnel..." - /etc/init.d/openvpn start - /etc/init.d/ipsec start - exit 0 -fi - -# Turn green off and red on -if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then - echo timer > $GREEN_LED/trigger - echo 100 | tee $GREEN_LED/delay_* - echo none > $RED_LED/trigger -fi - - -######################################### -### Generate private key if necessary ### -######################################### - -if [ ! -f $KEY_PATH ]; then - KEY_TEMP=$(mktemp -u) - - logger -t certidude -s "Generating RSA key for VPN..." - if [ -d $GREEN_LED ]; then - echo 250 | tee $GREEN_LED/delay_* - fi - - openssl gen$KEY_TYPE -out $KEY_TEMP $KEY_LENGTH - chmod 0600 $KEY_TEMP - mv $KEY_TEMP $KEY_PATH -fi - - -############################ -### Fetch CA certificate ### -############################ - -if [ ! -f $AUTHORITY_PATH ]; then - AUTHORITY_TEMP=$(mktemp -u) - - logger -t certidude -s "Fetching CA certificate from $URL/api/certificate/" - curl -f -s $URL/api/certificate/ > $AUTHORITY_TEMP - if [ $? -ne 0 ]; then - logger -t certidude -s "Failed to receive CA certificate, server responded: $(cat $AUTHORITY_TEMP)" - - if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then - echo none > $GREEN_LED/trigger - echo timer > $RED_LED/trigger - echo 100 | tee $RED_LED/delay_* - fi - - exit 10 - fi - - openssl x509 -in $AUTHORITY_TEMP -noout - if [ $? -ne 0 ]; then - logger -t certidude -s "Received invalid CA certificate" - - if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then - echo none > $GREEN_LED/trigger - echo timer > $RED_LED/trigger - echo 250 | tee $RED_LED/delay_* - fi - - exit 11 - fi - - mv $AUTHORITY_TEMP $AUTHORITY_PATH -fi - -logger -t certidude -s "CA certificate md5sum: $(md5sum -b $AUTHORITY_PATH)" - - -##################################### -### Generate request if necessary ### -##################################### - -if [ ! -f $REQUEST_PATH ]; then - REQUEST_TEMP=$(mktemp -u) - openssl req -new -sha256 -key $KEY_PATH -out $REQUEST_TEMP -subj "/CN=$COMMON_NAME" - mv $REQUEST_TEMP $REQUEST_PATH -fi - -logger -t certidude -s "Request md5sum is $(md5sum -b $REQUEST_PATH)" - -# Wait for certificate -if [ -d $GREEN_LED ]; then - echo 500 | tee $GREEN_LED/delay_* -fi - -CERTIFICATE_TEMP=$(mktemp -u) - -curl -f -L \ - -H "Content-Type: application/pkcs10" \ - --data-binary @$REQUEST_PATH \ - $URL/api/request/?autosign=true\&wait=yes > $CERTIFICATE_TEMP - -# TODO: Loop until we get exitcode 0 -# TODO: Use backoff time $((2\*X)) - -if [ $? -ne 0 ]; then - echo "Failed to fetch certificate" - - if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then - echo none > $GREEN_LED/trigger - echo timer > $RED_LED/trigger - echo 500 | tee $RED_LED/delay_* - fi - - exit 21 -fi - -# Verify certificate -openssl verify -CAfile $AUTHORITY_PATH $CERTIFICATE_TEMP - -if [ $? -ne 0 ]; then - logger -t certidude -s "Received bogus certificate!" - - if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then - echo none > $GREEN_LED/trigger - echo timer > $RED_LED/trigger - echo 1000 | tee $RED_LED/delay_* - fi - - exit 22 -fi - -logger -t certidude -s "Certificate md5sum: $(md5sum -b $CERTIFICATE_TEMP)" - -uci commit - -mv $CERTIFICATE_TEMP $CERTIFICATE_PATH - -# Restart services -/etc/init.d/ipsec start -/etc/init.d/openvpn start