So it seems like islocalnet can’t handle more than one IP address on an interface.
After clearing the 172.18.0.2/16 address off the interface, it now works:
root@ospd-openvas:/ospd-openvas# openvas-nasl -t 192.168.1.254 -i /var/lib/openvas/plugins/ /var/lib/openvas/plugins/nmap_mac.nasl -X -T out.log -d
lib misc-Message: 00:21:40.264: replace key Host/mac_address -> 14:49:BC:24:43:68
So what I was trying to achieve is to have the ospd-openvas container on the local network to allow it to see mac addresses, which provides two things for me:
- Provides a way to more-uniquely identify a host, as a mac address is usually more-reliable than an IP address, and
- Use the MAC OUI to identify the manufacturer and help narrow down what the host is.
The second thing I needed to make sure worked is to allow the container to use the host’s systemd-resolved service to conduct mDNS queries and reverse lookups on the local network, as moving to macvlan and using DHCP made the container stop seeing hostnames on the local network (as the resolver on the container doesn’t have the capability of running mDNS queries).
Notes:
- This was on a Ubuntu 22.04 server, which affects interface naming and the use of the systemd-resolved service
- This only works on a network with DHCP enabled. You can make this work with static IPs, but that wasn’t my intent here.
- The host will now consume two IP addresses from DHCP - one for the parent server, one for the ospd-openvas container.
- You could put all containers on the macvlan network, but all of them would be on the host’s physical network.
- The reason for using the openvas (bridge) network was that the container’s refer to each other by name, so host networking doesn’t work.
- I started with the docker-compose file from the community containers page.
So here’s how I did it if anyone was interested.
- Create two networks in compose:
networks:
macvlan_net:
driver: macvlan
driver_opts:
parent: eno1
openvas:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/24
gateway: 172.20.0.1
- Assign all containers to the openvas network. E.g.:
gvm-tools:
image: greenbone/gvm-tools
volumes:
- gvmd_socket_vol:/run/gvmd
- ospd_openvas_socket_vol:/run/ospd
depends_on:
- gvmd
- ospd-openvas
networks:
- openvas
- Set up ospd-openvas to:
a. Use a local build.
b. Use the host’s local network and local DNS server for builds.
c. Use both networks. (macvlan provides access to the local network, the openvas network allows access to all other hosts in the compose stack).
ospd-openvas:
build:
context: ./ospd-openvas
network: host
restart: on-failure
hostname: ospd-openvas.local
cap_add:
- NET_ADMIN # for capturing packages in promiscuous mode
- NET_RAW # for raw sockets e.g. used for the boreas alive detection
dns:
- 172.18.0.1 # Use the local server for builds
security_opt:
- seccomp=unconfined
- apparmor=unconfined
volumes:
- gpg_data_vol:/etc/openvas/gnupg
- vt_data_vol:/var/lib/openvas/plugins
- notus_data_vol:/var/lib/notus
- ospd_openvas_socket_vol:/run/ospd
- redis_socket_vol:/run/redis/
- openvas_data_vol:/etc/openvas/
- openvas_log_data_vol:/var/log/openvas
depends_on:
redis-server:
condition: service_started
gpg-data:
condition: service_completed_successfully
vulnerability-tests:
condition: service_completed_successfully
configure-openvas:
condition: service_completed_successfully
networks:
- macvlan_net
- openvas
-
Create a folder called ospd-openvas in the same folder as the docker-compose.yml file. Place this Dockerfile in there:
a. This dockerfile sets up the dhcp client, sets the container to use the parent-server’s DNS server rather than the one issued by DHCP, and lastly - run the DHCP client script as part of the startup.
FROM greenbone/ospd-openvas:22.7.1
# Install dhclient and clean up apt cache
RUN apt-get update && apt-get install -y isc-dhcp-client && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Allow the user to run dhclient without sudo
RUN mkdir -p /home/ospd-openvas/bin && echo 'dhclient' > /home/ospd-openvas/bin/dhclient && chmod +x /home/ospd-openvas/bin/dhclient && export PATH=/home/ospd-openvas/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# Make the script executable
COPY dhclient-script.sh /usr/local/bin/dhclient-script.sh
RUN chmod +x /usr/local/bin/dhclient-script.sh
# Override DNS from DHCP
RUN echo 'supersede domain-name-servers 172.20.0.1;' >> /etc/dhcp/dhclient.conf
# Ensure entrypoint runs with necessary permissions
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/dhclient-script.sh"]
CMD ["ospd-openvas", "--config", "/etc/gvm/ospd-openvas.conf", "-f", "-m", "666"]
- Place this in a file called dhclient-script.sh in the same ospd-openvas folder.
a. This file remove’s the initial default route to the parent-host, removes the docker-issued IP from the macvlan network, runs the dhcp-client and then runs the usual openvas comman.
#!/bin/sh
# Clear the existing default route issued by Docker
ip route del default
# Clear the eth0 interface to remove the macvlan-assigned IP address (Breaks nmap mac address check (nmap_mac.nasl))
ip addr flush dev eth0
# Run dhclient to obtain an IP address
dhclient eth0
# Run the main entrypoint
exec /usr/local/bin/entrypoint ospd-openvas --config /etc/gvm/ospd-openvas.conf -f -m 666
- Lastly, you need to configure systemd-resolved to listen to requests from a non-localhost network.
a. Add DNSStubListenerExtra to /etc/systemd/resolved.conf and restart the service using sudo service systemd-resolved restart
[Resolve]
DNSStubListenerExtra=172.20.0.1
Hope that helps anyone looking to do what I was.
I’m kinda-expecting someone to tell me that there was a way-easier way of doing this. I’d be happy to hear if that is the case.