For me, most any work day consists of Ubuntu Server, Docker, Ansible, Python, and Golang; but not all server instances have Static IP addresses, some only have an Ephemeral IP address. When I need to pass an interface’s address to systemd, shell script, Docker, Kubernetes, etc. without having to perform edits on code or configuration, this can become problematic.
An easy way to do so is with setup-network-environment
via system initialization and optionally, VPN connection parameters (e.g. OpenVPN’s up
and down
options). Running this program will produce (and subsequently update) an environment file (by default, located at /etc/network-environment
) that can be parsed by Bash, systemd, and others, in order to populate variables.
An example of the generated environment file:
LO_IPV4=127.0.0.1
ENO16777736_IPV4=192.168.12.10
DEFAULT_IPV4=192.168.12.10
TUN0_IPV4=172.16.12.10
Prerequisites
- Snappy (package manager) – based upon Go’s documentation, used for installing the latest version of Go.
- Git version control system
- Go (programming language)
In this article, I’ll assume that these prerequisites haven’t been fulfilled (Snappy, Git, and Go aren’t part of the standard install for Ubuntu Server 16 LTS), and will cover those installation processes as well.
Setup
Update the package cache:
sudo apt update
Set ~/.bashrc
to be loaded by ~/.bash_profile
:?
echo 'source $HOME/.bashrc' >> $HOME/.bash_profile
Snappy
Since Ubuntu 18.04 and later include Snappy, you can skip this step if this is what you’re using.
Install Snappy:
sudo apt install --yes snapd
Toolkit
Install build tools and Git:
sudo apt install --yes \
build-essential \
git \
;
Golang
After you perform this step, please logout, and log back in. If you don’t, Golang will not properly function for the next step.
Install the latest version of Golang:
snap install --classic go
The reason that I set $GOBIN
to /usr/local/bin
is because I want Go-based binaries to be accessible by the entire system. In a multi-user environment, your needs may differ, and plenty of people use $GOPATH/bin
, and update $PATH
, to reflect these utilities existing in their home directories.
That said, there’s plenty of discussion on the Internet about what this should be set to 1 2, so, YMMV.
Furthermore, the reason that I don’t simply call source /etc/network-environment
, is due to Bash not being able to parse variables with dashes in them (this seems to happen on particular Linux instances.)
Append environment variables to ~/.bashrc
:
cat << 'EOF' | tee --append $HOME/.bashrc > /dev/null
# Golang
export GOPATH=$HOME/go
export GOBIN=/usr/local/bin
export PATH=$GOBIN:$PATH
# setup-network-environment
if [ -f /etc/network-environment ]; then
tnef=`mktemp`
cp -a /etc/network-environment ${tnef}
sed --in-place 's~[^0-9A-Za-z\=\.\_/]\+~_~g' ${tnef}
source ${tnef}
export $(cut -d= -f1 ${tnef})
rm -rf ${tnef}
fi
EOF
You should logout and log back in now.
setup-network-environment
Download, build, and install setup-network-environment
:
go get github.com/kelseyhightower/setup-network-environment
Configure
systemd
If you need to refresh your memory on basic systemd commands, please see my systemd shortcuts snippet.
Service
Save the following contents to /etc/systemd/system/setup-network-environment.service
[Unit]
Description=Setup Network Environment
Documentation=https://github.com/kelseyhightower/setup-network-environment
Requires=network.target
After=network.target
[Service]
ExecStart=/usr/local/bin/setup-network-environment
RemainAfterExit=yes
Type=oneshot
[Install]
WantedBy=multi-user.target
Create an environment variable to use for the next set of commands:
sysDserviceSaveFile=/etc/systemd/system/setup-network-environment.service
Run the following set of commands together, including the curly braces:
{
if $? -eq 0; then echo "Working on ${sysDserviceSaveFile}"; else echo "Unknown variable"; exit; fi
# Set permissions
chmod -v 644 ${sysDserviceSaveFile}
# Reload management parameters
systemctl daemon-reload
# Enable system service
systemctl enable "${sysDserviceSaveFile}"
# Start system service
systemctl start "${sysDserviceSaveFile}"
# Check status
systemctl status "${sysDserviceSaveFile}"
}
View generated environment file:
cat /etc/network-environment
Example dependencies
In the next few pages, I’ll cover examples where setup-network-environment
is used with other programs:
- Launching Nginx with Docker.
- Updating
/etc/network-environment
when a VPN connection is started and stopped.