tuto2: wg working

This commit is contained in:
nemunaire 2019-03-14 06:46:09 +01:00
parent cd848e3ff6
commit 33f0698f1e
9 changed files with 196 additions and 30 deletions

2
.gitignore vendored
View File

@ -10,6 +10,8 @@ server-kernel
tuto2-cmdline
tuto2-initrd.img
tuto2.iso
tuto2-srs.iso
tuto2-srs.iso.gz
tuto2-kernel
tuto2-state/
tuto3-cmdline

View File

@ -33,14 +33,18 @@ tuto2-initrd.img: tuto2.yml
tuto2-cmdline: tuto2.yml
linuxkit build $<
tuto2.iso: pkg/debian-tuto2/isolinux.cfg tuto2-kernel tuto2-initrd.img tuto2-cmdline
tuto2.iso: tuto2.yml tuto2-kernel tuto2-initrd.img tuto2-cmdline
linuxkit build -format iso-bios $<
tuto2-srs.iso: tuto2.iso pkg/debian-tuto2/isolinux.cfg
$(eval TDIR := $(shell mktemp -d))
mkdir $(TDIR)/boot/ $(TDIR)/isolinux/
cp tuto2-kernel $(TDIR)/boot/kernel
cp tuto2-initrd.img $(TDIR)/boot/tuto2ird.img
bsdtar xf $< -C $(TDIR)
cp pkg/debian-tuto2/isolinux.cfg /usr/share/syslinux/isolinux.bin /usr/share/syslinux/ldlinux.c32 /usr/share/syslinux/vesamenu.c32 /usr/share/syslinux/menu.c32 /usr/share/syslinux/libcom32.c32 /usr/share/syslinux/libutil.c32 /usr/share/syslinux/poweroff.c32 $(TDIR)/isolinux/
$(eval CMDLINE := $(shell cat tuto2-cmdline))
$(eval CMDLINE := $(shell cat tuto2-cmdline | sed 's/console=ttyS0 //;s#root=/dev/sr0 ##;s#root=/dev/sda1 ##;s#adlin.format=/dev/sda ##;'))
sed -i 's#<CMDLINE>#$(CMDLINE)#' $(TDIR)/isolinux/isolinux.cfg
genisoimage -o $@ -l -J -R -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -joliet-long -input-charset utf8 -V AdLin2 $(TDIR)
mkisofs -o $@ -l -J -R -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -joliet-long -input-charset utf8 -V AdLin2 $(TDIR)
rm -rf $(TDIR)
isohybrid $@
tuto2-srs.iso.gz: tuto2-srs.iso
gzip -9 < $< > $@

View File

@ -2,10 +2,13 @@ FROM debian
RUN apt-get update && apt-get install --no-install-recommends -y \
busybox \
ca-certificates \
console-data \
cron \
curl \
ifupdown \
kbd \
kmod \
nano \
openssh-server \
python \
@ -15,10 +18,13 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
vim.tiny \
&& rm -rf /var/lib/apt/lists/*
RUN curl -L -o /tmp/wireguard.deb http://httpredir.debian.org/debian/pool/main/w/wireguard/wireguard-tools_0.0.20190227-1_amd64.deb && dpkg -i /tmp/wireguard.deb; rm /tmp/wireguard.deb
RUN rm -rf /etc/init.d/ && \
mkdir /overlay && \
ln -sf /init /sbin/init && \
ln -sf /lib/systemd/system/systemd-netwkord.service /etc/systemd/system/multi-user.target.wants/systemd-networkd.service
COPY default.script /etc/udhcpc/default.script
COPY issue /etc/issue
COPY sshd_config /etc/ssh/sshd_config

60
pkg/debian-tuto2/default.script Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
# Busybox udhcpc dispatcher script. Copyright (C) 2009 by Axel Beckert.
#
# Based on the busybox example scripts and the old udhcp source
# package default.* scripts.
RESOLV_CONF="/etc/resolv.conf"
case $1 in
bound|renew)
/bin/ip address add dev $interface $ip/$subnet
if [ -n "$router" ]; then
echo "$0: Resetting default routes"
while /bin/ip route del default via 0.0.0.0 dev $interface; do :; done
metric=0
for i in $router; do
/bin/ip route add default via $i dev $interface metric $metric
metric=$(($metric + 1))
done
fi
# Update resolver configuration file
R=""
[ -n "$domain" ] && R="domain $domain
"
for i in $dns; do
echo "$0: Adding DNS $i"
R="${R}nameserver $i
"
done
if [ -x /sbin/resolvconf ]; then
echo -n "$R" | resolvconf -a "${interface}.udhcpc"
else
echo -n "$R" > "$RESOLV_CONF"
fi
;;
deconfig)
if [ -x /sbin/resolvconf ]; then
resolvconf -d "${interface}.udhcpc"
fi
/bin/ip a del dev $interface
;;
leasefail)
echo "$0: Lease failed: $message"
;;
nak)
echo "$0: Received a NAK: $message"
;;
*)
echo "$0: Unknown udhcpc command: $1";
exit 1;
;;
esac

View File

@ -0,0 +1,30 @@
DEFAULT vesamenu.c32
MENU RESOLUTION 1024 768
menu background #00000000 * *
menu color title * #FF22BBCC *
menu color sel * #FFFFFFFF #FF22BBCC *
menu color hotsel 1;7;37;40 #ffffffff #76a1d0ff *
menu tabmsg Press ENTER to boot or TAB to edit a menu entry
prompt 0
timeout 0
menu title Welcome to the EPITA ADvanced LINux administration course!
LABEL tutorial-nohdd
MENU LABEL ^Erase my first drive if necessary, then enter tutorial
KERNEL /boot/kernel
APPEND <CMDLINE> adlin.format=/dev/sda root=/dev/sda1 root=/dev/sr0
LABEL tutorial-hdd
MENU LABEL Enter tutorial without erasing ^disk
KERNEL /boot/kernel
APPEND <CMDLINE> root=/dev/sda1 root=/dev/sr0
MENU SEPARATOR
LABEL poweroff
MENU LABEL ^Shutdown
KERNEL poweroff.c32

View File

@ -11,7 +11,7 @@
# default value.
#Port 22
#AddressFamily any
AddressFamily inet
#ListenAddress 0.0.0.0
#ListenAddress ::

View File

@ -92,7 +92,7 @@ func rawHandler(f func(*http.Request, httprouter.Params, []byte) (interface{}, e
// Read the body
if r.ContentLength < 0 || r.ContentLength > 6553600 {
http.Error(w, fmt.Sprintf("{errmsg:\"Request too large or request size unknown\"}", err), http.StatusRequestEntityTooLarge)
http.Error(w, "{errmsg:\"Request too large or request size unknown\"}", http.StatusRequestEntityTooLarge)
return
}
var body []byte

View File

@ -8,6 +8,7 @@ import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
"time"
@ -30,7 +31,7 @@ func init() {
return getTunnelInfo(student.Id), nil
}))
router.POST("/api/wg/", apiAuthHandler(genWgToken))
router.POST("/api/wg/:token", apiHandler(getWgTunnelInfo))
router.POST("/api/wg/:token", getWgTunnelInfo)
}
func showWgTunnel(student Student, ps httprouter.Params, body []byte) (interface{}, error) {
@ -68,32 +69,57 @@ type PubTunnel struct {
PubKey []byte
}
func getWgTunnelInfo(ps httprouter.Params, body []byte) (interface{}, error) {
func getWgTunnelInfo(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if addr := r.Header.Get("X-Forwarded-For"); addr != "" {
r.RemoteAddr = addr
}
log.Printf("%s \"%s %s\" [%s]\n", r.RemoteAddr, r.Method, r.URL.Path, r.UserAgent())
// Read the body
if r.ContentLength < 0 || r.ContentLength > 6553600 {
http.Error(w, "{errmsg:\"Request too large or request size unknown\"}", http.StatusRequestEntityTooLarge)
return
}
// Access wg infos
tokenhex := []byte(ps.ByName("token"))
tokendec := make([]byte, hex.DecodedLen(len(tokenhex)))
n, err := hex.Decode(tokendec, tokenhex)
if err != nil {
return nil, err
http.Error(w, fmt.Sprintf("{errmsg:%q}", err), http.StatusBadRequest)
return
}
token, err := GetTunnelToken(tokendec[:n])
if err != nil {
return nil, err
http.Error(w, fmt.Sprintf("{errmsg:%q}", err), http.StatusBadRequest)
return
}
var pt PubTunnel
if err := json.Unmarshal(body, &pt); err != nil {
return nil, err
if err := json.NewDecoder(r.Body).Decode(&pt); err != nil {
http.Error(w, fmt.Sprintf("{errmsg:%q}", err), http.StatusBadRequest)
return
}
token.PubKey = pt.PubKey
_, err = token.Update()
if err != nil {
return nil, err
http.Error(w, fmt.Sprintf("{errmsg:%q}", err), http.StatusBadRequest)
return
}
return getTunnelInfo(token.IdStudent), nil
tinfo := getTunnelInfo(token.IdStudent)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(fmt.Sprintf(`[Peer]
PublicKey = %s
Endpoint = %s:%d
AllowedIPs = ::/0
PersistentKeepalive = 5
# MyIPv6=%s1/%d
# GWIPv6=%s
`, base64.StdEncoding.EncodeToString(tinfo.SrvPubKey), "82.64.31.248", tinfo.SrvPort, tinfo.CltIPv6, 64, tinfo.SrvGW6)))
}
@ -206,9 +232,9 @@ func GenWGConfig(w io.Writer) (error) {
w.Write([]byte(fmt.Sprintf(`[Peer]
#IdStudent = %d
#TokenText = %s
PublicKey = %s
AllowedIPs = %s/%d`, t.IdStudent, t.TokenText, base64.StdEncoding.EncodeToString(t.PubKey), studentIP(t.IdStudent), 80)))
AllowedIPs = %s/%d
`, t.IdStudent, base64.StdEncoding.EncodeToString(t.PubKey), studentIP(t.IdStudent), 80)))
}
return nil

View File

@ -1,11 +1,11 @@
kernel:
image: linuxkit/kernel:4.9.85
image: linuxkit/kernel:4.20.3
# cmdline: "console=ttyS0 console=tty0"
# cmdline: "console=tty0 console=ttyS0 root=/dev/sda1 root=/dev/sr0 adlin.net=easy"
cmdline: "console=tty0 console=ttyS0 root=/dev/sda1 root=/dev/sr0"
cmdline: "console=tty0 console=ttyS0 root=/dev/sda1 root=/dev/sr0 adlin.format=/dev/sda quiet"
init:
- nemunaire/adlin-tuto2:8f13bab1bcb9b7b3f977ffd0f32bf596412b7094-dirty
- nemunaire/adlin-tuto2:35a9354900bb9a419e9e54758c069e8b97472ec5-dirty
files:
- path: etc/hostname
@ -16,6 +16,7 @@ files:
- path: etc/resolv.conf
contents: |
nameserver 9.9.9.9
nameserver 1.1.1.1
mode: "0644"
- path: etc/systemd/network/49-main.link
@ -27,15 +28,13 @@ files:
mode: "0644"
- path: etc/systemd/network/50-dhcp.network
contents: ""
mode: "0644"
- path: etc/systemd/network/.50-dhcp
contents: |
[Match]
Name=eth0
[Network]
DHCP=yes
IPv6AcceptRA=no
LinkLocalAddressing=no
mode: "0644"
- path: init
@ -61,7 +60,7 @@ files:
INITP=$(cmdline init)
[ -z "$INITP" ] && INITP=/lib/systemd/systemd
WGTOKEN=$(cmdline adlin.token)
ROOTFS=$(cmdline root)
@ -74,6 +73,7 @@ files:
[ -b "$ROOTFS" ] || { echo "Invalid provided rootfs: not a valid block device."; exit 1; }
}
mkdir -p /overlay
/bin/mount -n -t tmpfs none /overlay
/bin/mkdir -p /overlay/rwdata
@ -93,10 +93,7 @@ files:
mkdir -p ${ovr_rwdata}/work
/bin/mount -n -t overlay -o upperdir=${ovr_rwdata}/data,workdir=${ovr_rwdata}/work,lowerdir=${ovr_robase} overlay ${ovr_combined} || { echo "Unable to create overlayfs."; exit 3; }
grep adlin.net=easy /proc/cmdline > /dev/null && mount --bind ${ovr_combined}/etc/systemd/network/.50-dhcp ${ovr_combined}/etc/systemd/network/50-dhcp.network
/bin/umount -n /proc
/bin/umount -n /dev
/bin/mkdir -p ${ovr_combined}/overlay/rwdata
/bin/mount -n --move ${ovr_rwdata} ${ovr_combined}/overlay/rwdata
@ -106,8 +103,49 @@ files:
cd ${ovr_combined}
mount --move /dev dev
mount --move . /
/bin/umount -n /overlay
# Setting up wireguard tunnel
[ -z "${WGTOKEN}" ] && [ -f "etc/adlin.token" ] && WGTOKEN=$(cat etc/adlin.token)
[ -z "${WGTOKEN}" ] && {
echo -n "You didn't define your token to connect the network. Please copy it here now: "
read WGTOKEN
}
echo -n "${WGTOKEN}" > etc/adlin.token
/sbin/sysctl -w net.ipv6.conf.eth0.autoconf=0
/bin/ip link set up dev eth0
/bin/busybox udhcpc -n -q
[ -f "etc/wireguard/adlin.conf" ] && WGPRVKEY=$(sed 's/^.*PrivateKey *= *//p;d' etc/wireguard/adlin.conf)
[ -z "${WGPRVKEY}" ] && WGPRVKEY=$(/usr/bin/wg genkey)
WGPUBKEY=$(echo $WGPRVKEY | /usr/bin/wg pubkey)
while ! { echo "[Interface]\nPrivateKey = ${WGPRVKEY}"; /usr/sbin/chroot . /usr/bin/curl -f -d '{"pubkey": "'$WGPUBKEY'"}' https://adlin.nemunai.re/api/wg/$(echo -n "$WGTOKEN" | /usr/bin/sha512sum | /usr/bin/cut -d ' ' -f 1); } > etc/wireguard/adlin.conf
do
echo ""
echo "****************************************"
echo "******* SWITCHING TO RESCUE MODE *******"
echo "****************************************"
echo ""
echo "Sorry, I was unable to establish a connection to adlin.nemunai.re."
echo "Please verify that your primary network interface can obtain an IPv4 through DHCP."
echo ""
echo "Dropping to a shell, please fix your network, then press Ctrl+D or exit to retry."
echo ""
echo "****************************************"
echo ""
/bin/busybox cttyhack /usr/sbin/chroot . /bin/sh
echo "Retrying connection..."
done
/sbin/modprobe wireguard
/bin/ip link add dev wg0 type wireguard
/usr/bin/wg setconf wg0 etc/wireguard/adlin.conf
/bin/ip address add dev wg0 $(sed 's/^.*MyIPv6=//p;d' etc/wireguard/adlin.conf)
/bin/ip link set up dev wg0
/bin/ip -6 route del default
/bin/ip -6 route add default via $(sed 's/^.*GWIPv6=//p;d' etc/wireguard/adlin.conf) pref high
# To the user
exec /usr/sbin/chroot . "${INITP}"
mode: "0755"
@ -149,7 +187,7 @@ files:
- path: etc/shadow
contents: |
root:$6$fCh6fLfB$wTiBuIJB2/QLl37VlJ16MsqGmfSDct8ALRpY8kemFC2T4N4eZgdlTnEqTuYn5i4FMc5GoDBx1nfENHQqm0Zgm.:17594:0:99999:7:::
root:$6$B0qzwsEh$vfWGpIFUrKGrkT0PVtGhhomBwc.60IBIxjMLyG8mz.NJLFRryjqLK9sA/mzxNSaQViiHsYYrsgmcWVHblfdHg1:17968:0:99999:7:::
daemon:*:17575:0:99999:7:::
bin:*:17575:0:99999:7:::
sys:*:17575:0:99999:7:::