I am still not able to get a valid curl
response from outside the docker container, even when following your modified curl
command:
user@device:~$ curl --location -k --request POST 'https://10.151.200.182/retrieve' --form data='{"op": "showConfig", "path": []}' --form key='thepass'
curl: (7) Failed to connect to 10.151.200.182 port 443: Connection refused
user@device:~$
These are the steps I followed, with much more detail.
I can see that port 443
is not exposed from inside the VyOS container when I run ss -lntp
.
When I run ss -lntp
from the docker host, I can see that the port is available.
user@host:~$ ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 5 127.0.0.1:631 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:443 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 5 [::1]:631 [::]:*
LISTEN 0 4096 [::]:443 [::]:*
So far, only the 127.0.0.1:8080
server shows up from inside the docker container.
VyOS program setup
Docker network setup for VyOS
Enable IPv6 for VyOS
- Enter root with
sudo -i
- Stop docker daemon with
systemctl stop docker
.
- Run
cat /etc/docker/daemon.json
. If that command fails, then continue normally.
- create a
daemon.json
file in the directory /etc/docker
with the command echo -e '{\n "ipv6": true,\n "fixed-cidr-v6": "2001:db8::/64"\n}' > /etc/docker/daemon.json
.
- Start the docker daemon with
systemctl start docker
.
- Exit root user with
exit
.
- If step 3 runs, and a
/etc/docker/daemon.json
is found, then simply add these 2 lines of json
to the file:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8::/64"
}
Create container network interface
In order to get the Docker container to communicate with the host on the network interface that links to the engineering entwork, a macvlan driver must be used.
This command creates the docker macvlan interface.
docker network create -d macvlan --subnet=10.151.192.0/20 --gateway=10.151.192.1 -o parent=enp88s0 macvlan-vyos-driver
Host network setup for VyOS
The host OS now needs to create an interface to connect the container to the outside network.
Run this command to generate the macvlan interface on the host OS:
# create the macvlan device
sudo ip link add demo-nuc-vyos link enp88s0 type macvlan mode bridge
# Assign the device an IP address
sudo ip addr add 10.151.200.182/20 dev demo-nuc-vyos
# Bring up the interface
sudo ip link set demo-nuc-vyos up
Note: enp88s0
is the host network interface connected to the internet.
VyOS setup docker container
Create VyOS from ISO image
Run these commands to create the docker image.
mkdir vyos && pushd vyos
wget https://s3-us.vyos.io/rolling/current/vyos-1.4-rolling-202305010317-amd64.iso
# shortname="1.4-rolling-202305010317"
# Grab the latest vyos ISO file by download date to the filesystem.
isofile=$(ls -t | grep "vyos-" | head -n 1)
# The name without cpu architecture nor vyos header
shortname=$(echo $isofile | sed 's/vyos-//g' | sed 's/-amd64.iso//g')
# Now for the rest of the script that uses these variables
mkdir rootfs
sudo mount -o loop $isofile rootfs
# sudo apt-get install -y squashfs-tools
mkdir unsquashfs
sudo unsquashfs -f -d unsquashfs/ rootfs/live/filesystem.squashfs
sudo tar -C unsquashfs -c . | docker import - vyos:$shortname
sudo umount rootfs
popd
# Deleting the directory is optional
sudo rm -rf vyos
Run this command to create the docker container.
This command should be run in the same terminal as the previous commands.
# Create the container without the macvlan and then attach the macvlan after the fact
docker run -d --rm -p 443:443/udp -p 443:443 --name vyos --privileged -v /lib/modules:/lib/modules -v $(pwd)/config:/config vyos:1.4-rolling-202305010317 /sbin/init
# Attach after the fact
docker network connect macvlan-vyos-driver vyos
# Only when the macvlan is attached after the fact do I see the ports exposed in "docker port".
Then run this command to enter the docker container inside the VyOS process.
docker exec -ti vyos su vyos
Configure HTTP API
Enter the VyOS process with docker exec -ti vyos su vyos
.
Then run these commands:
cd ~
mkdir -p config
pushd config
configure
set service https api debug
set service https api keys id theid key thepass
commit
save
exit
Validate HTTP API is enabled
Enabled for localhost
Query the VyOS container to make sure the HTTP API is listening for requests with this curl
command:
vyos@84fa1e0505fa:/$ curl --location --request POST 'http://127.0.0.1:8080/retrieve' --form data='{"op": "showConfig", "path": []}' --form key='thepass'
{"success": true, "data": {"interfaces": {"loopback": {"lo": {}}}, "service": {"https": {"api": {"debug": {}, "keys": {"id": {"theid": {"key": "thepass"}}}}}, "ntp": {"allow-client": {"address": ["0.0.0.0/0", "::/0"]}, "server": {"time1.vyos.net": {}, "time2.vyos.net": {}, "time3.vyos.net": {}}}}, "system": {"config-management": {"commit-revisions": "100"}, "conntrack": {"modules": {"ftp": {}, "h323": {}, "nfs": {}, "pptp": {}, "sip": {}, "sqlnet": {}, "tftp": {}}}, "console": {"device": {"ttyS0": {"speed": "115200"}}}, "host-name": "vyos", "login": {"user": {"vyos": {"authentication": {"encrypted-password": "$6$QxPS.uk6mfo$9QBSo8u1FkH16gMyAVhus6fU3LOzvLR9Z9.82m3tiHFAxTtIkhaZSWssSgzt4v4dGAL8rhVQxTg0oAG9/q11h/", "plaintext-password": ""}}}}, "syslog": {"global": {"facility": {"all": {"level": "info"}, "protocols": {"level": "debug"}}}}}}, "error": null}
vyos@84fa1e0505fa:/$
Enabled for the docker host
Query the docker host to make sure the HTTP API is listening for requests with this curl
command:
user@device:~$ curl --location -k --request POST 'https://10.151.200.182/retrieve' --form data='{"op": "showConfig", "path": []}' --form key='thepass'
curl: (7) Failed to connect to 10.151.200.182 port 443: Connection refused
user@device:~$
And that is where I am getting the failure. Below I have provided the network interface configuration for the docker host:
user@device:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp88s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 1c:69:7a:ad:d5:67 brd ff:ff:ff:ff:ff:ff
inet 10.151.192.144/20 brd 10.151.207.255 scope global dynamic noprefixroute enp88s0
valid_lft 83777sec preferred_lft 83777sec
inet6 fe80::8a6a:f833:d555:cae/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: enx00e04c6803c9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:e0:4c:68:03:c9 brd ff:ff:ff:ff:ff:ff
4: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 60:e3:2b:35:12:31 brd ff:ff:ff:ff:ff:ff
altname wlp0s20f3
inet 10.151.193.171/20 brd 10.151.207.255 scope global dynamic noprefixroute wlo1
valid_lft 83775sec preferred_lft 83775sec
inet6 fe80::564d:b959:2b6b:9e0a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:37:21:d8:4a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 2001:db8::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::42:37ff:fe21:d84a/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::1/64 scope link
valid_lft forever preferred_lft forever
6: demo-nuc-vyos@enp88s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 72:69:5b:ad:2a:0b brd ff:ff:ff:ff:ff:ff
inet 10.151.200.182/20 scope global demo-nuc-vyos
valid_lft forever preferred_lft forever
inet6 fe80::7069:5bff:fead:2a0b/64 scope link
valid_lft forever preferred_lft forever
9: vethb9a86e7@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 42:24:0f:66:09:8f brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::4024:fff:fe66:98f/64 scope link
valid_lft forever preferred_lft forever
And here is the ip addr show
from inside the container:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 fe80::200:ff:fe00:0/64 scope link
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8::242:ac11:2/64 scope global nodad
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
10: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:0a:97:c0:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.151.192.2/20 brd 10.151.207.255 scope global eth1
valid_lft forever preferred_lft forever
I have also validated the ports are open with docker network
:
user@device:~$ docker port vyos
443/tcp -> 0.0.0.0:443
443/tcp -> [::]:443
443/udp -> 0.0.0.0:443
443/udp -> [::]:443
I can also see that the container has a proper external subnet connection because the VyOS commands in configure
mode show it:
vyos@84fa1e0505fa# run show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface IP Address S/L Description
--------- ---------- --- -----------
eth0 172.17.0.2/16 u/u
2001:db8::242:ac11:2/64
eth1 10.151.192.2/20 u/u
lo 127.0.0.1/8 u/u
::1/128
[edit]
vyos@84fa1e0505fa#
The 10.151.192.0/20
subnet still needs access to the HTTP api.
What am I doing wrong? What else shoul I be trying?