Creating a Secure TAK Server On Docker via CentOS 7
I’ve been working on getting a TAK server up all weekend. There are a few detailed Resouces out there, but somehow they all seem to miss the mark on walking the user from A to Z of creating a secure TAK server for personal use. So here I will document how to create one in the cloud, as a reference for myself and others.
Choosing a Host
You may host them on your own hardware or the cloud. The minimum specs recommended are:
- 4 processor cores
- 8 GB RAM
- 40 GB disk storage
I will be using Linode for the guide to deploy a 2GB CentOS7 VM in the cloud. Because of the little ram, this means the server will run slowly, so I suggest you go with 8GB is possible.
Creating a User, Installing Docker, and Assigning Permissions
This guide will not go over the installation of CentOS7 itself, but will start at a fresh install logged in as the root user. We will create a user (takusr) with sudo ability, and give it docker permission to manage containers.
We always start these by doing an OS update:
sudo yum check-update
User Creation
Create a user to manage the containers, and assign it a password:
adduser takusr
passwd takusr
Add it to the sudo group, and swap to the new user:
gpasswd -a takusr wheel
su - takusr
And let’s make sure the ssh server is enabled so we can login remotely if needed.
It is advised to disable password login for both root and your newly created user and use PKI instead for security reasons, but that is out of the scope for this guide. You can find out how to do it here: https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
sudo systemctl enable sshd
sudo systemctl start sshd
Docker Installation and setting permissions
curl -fsSL https://get.docker.com/ | sh
sudo systemctl start docker
sudo systemctl status docker
sudo systemctl enable docker
sudo usermod -aG docker takusr
You must now log out of your current session, and come back for the permission to take effect. We will also test them by running the hello-world docker command under out takusr.
exit
su - takusr
docker run hello-world
TakServer Installation
Grab a copy of the Tak Server 4.9.0 from https://tak.gov/products/tak-server?product_version=tak-server-4-9-0. At the time of writing, 4.10.0 is out, but the docker container has a database user creation issue.
There are a few ways you can transfer this zip file. Most windows install now ship with scp, so will be using that.
Open a command Prompt in the location where the zip file was downloaded and issue the following command to transfer it to your TAK Server within the takusr home folder. Replace the IP with your servers.
scp takserver-docker-4.9-RELEASE-46.zip takusr@10.10.10.100:/
Back on the server, we will now install unzip, use it to extract the uploaded file.
sudo yum install unzip
unzip takserver-docker-4.9-RELEASE-46.zip -d taksrv
Now we will make some changes to the configuration file for the server to allow authentication via TLS port, and remove the ability to login with unencrypted insecure ports. If you’ve been following along, the folder and file paths will be exactly the same.
#Backup The configuration File
cp /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml.bak
#Remove the Lines allowing insecure access.
sed -i. '6,8d' /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml
sed -i. '9d' /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml
#Now we Open it up:
nano /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml
Now we need to add the following line in the field right after the “<netowrk multicastTTL=”5″>” that is on line 5. If using nano
#Insert as a new line:
<input _name="stdssl" protocol="tls" port="8089" auth="x509"/>
We also need to set a databasse password.
You can use Ctrl+W and search for “password” if using nano to find the following line:
Press Crtl +X Then Y + Enter to Save
Server Certificate Generation
Now we will create the server certificate. This will be what allows encrypted communication with the server from the clients. We will change into the directory where the cert scripts are held, edit the cert creation script helper, and then build a Root CA, An Issuing CA, and then a Server Certificate.
#Install Java/Openssl, as we need it for key generation
sudo yum install java
sudo yum install openssl
#Change into the Cert Scripts Folder
cd /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/certs/
#Make the scripts Executable
chmod +x *
#Edit the "cert-metadata.sh"
nano cert-metadata.sh
#Change the values below after the equal sign, and then save the file.
#COUNTRY=US
#STATE=${STATE}
#CITY=${CITY}
#ORGANIZATION=${ORGANIZATION:-TAK}
#ORGANIZATIONAL_UNIT=${ORGANIZATIONAL_UNIT}
Now we will actually create our server certs.
#Create root certificate authority
./makeRootCa.sh --ca-name namehere
#Example:
#./makeRootCa.sh --ca-name PENTAK-ROOT-CA
Take Special note of the name you use here, this is known as your Issuing certificate authority, and will be needed later.
#Create issuing certificate authority
./makeCert.sh ca namehere
#Example:
#./makeCert.sh ca PENTAK-ISSUING-CA
#At this point, the script will ask if you want to move files around so that future server/clients are signed by the new CA.
CHOOSE YES
We can view the details of out certs with the following commands to make sure they turned out okay.
keytool -list -v -keystore files/truststore-root.jks
#Replace "PENTAK-ISSUING-CA" with the name you used above for the issuing authority
keytool -list -v -keystore files/PENTAK-ISSUING-CA-signing.jks
The last certificate we need to generate is actually for the server, signed by our CA we just created:
Take Special note of the name you use here, this is known as your server certificate, and will be important in a moment.
./makeCert.sh server PENTAK-SERVER
Create the Docker Network
Issue the following command to create the docker network.
#We must run this from within the root foldler of the extracted zip
cd /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/
#Creates the network between our future database contianer, and TAK container.
docker network create takserver-"$(cat tak/version.txt)"
Build and Run the Database Container
First we build the database, and then run it. these comaands must be issued in the root of the extaacted folder, where the “docker” and “tak” files are.
#make sure we are in the root folder of the extracted zip
cd /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/
#Build the container
docker build -t takserver-db:"$(cat tak/version.txt)" -f docker/Dockerfile.takserver-db .
#Run the Container
docker run -d -v $(pwd)/tak:/opt/tak:z -it -p 5432:5432 --network takserver-"$(cat tak/version.txt)" --network-alias tak-database --name takserver-db-"$(cat tak/version.txt)" takserver-db:"$(cat tak/version.txt)"
Not we must get the docker internal IP address of the database container to edit the CoreConfig file once more to point to the correct location.
#List Containers
docker ps
#Note the container ID on the left
docker inspect cotnaineridhere
Take note of the IP Address on the output, as we need to use it next.
Final Configuration
Open the CoreConfig Configuration Once more.
nano /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml
Now, we need to change the names of the keystoreFile (The Server Certificate we built earlier), and the truststoreFile(The Issuing Certificate Authority) we made earlier in the config file.
Ctrl + W to Search for “takserver.jks”, and replace it, and “truststore-root.jks” with the names you used earlier. The Issuing Authority is prepended with “truststore-” as seen in your tak/certs/files folder.
If you plan to use federation, also rmeove the comment blocks above and below the <federation> section, and change the keystoreFile to your Server Certificate Name
Ctrl+X and then Y, Enter to save the file.
Next we can validate that the confile is okay by using the build in validation script:
#Make it executable
chmod +x /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/validateConfig.sh
#Run the Check
/home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/./validateConfig.sh /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/CoreConfig.example.xml
Now we must edit the pg_hba.conf file within tak/db-utils/ to make sure the correct network is configured for the database container.
nano /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/db-utils/pg_hba.conf
Scroll to the bottom where you see “host all all SomeIP md5/peer”
Here, you will insert a new line under “IPv4 local connections:”
Change the IP to reflect the gateway from the database docker container inspect command.
(Usually only the second octet changes.)
host all all 172.18.0.0/16 md5
Restart the Database Docker container so the changes take effect.
#List the containers to get the id
docker ps
#Stop the Container
docker stop idhere
#Start the container
docker start idhere
Building and Running the TAK Server
#make sure we are in the root folder of the extracted zip
cd /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/
#Build the container
docker build -t takserver:"$(cat tak/version.txt)" -f docker/Dockerfile.takserver .
#Run the Container
docker run -d -v $(pwd)/tak:/opt/tak:z -it -p 8080:8080 -p 8089:8089 -p 8443:8443 -p 8444:8444 -p 8446:8446 -p 8087:8087/tcp -p 8087:8087/udp -p 8088:8088 -p 9000:9000 -p 9001:9001 --network takserver-"$(cat tak/version.txt)" --name takserver-"$(cat tak/version.txt)" takserver:"$(cat tak/version.txt)"
Creating User and Admin Certs
Because we are using TLS/SSL, we need to create certificates to authenticate with the server securely. Ideally, every device should have it’s own certificate. We will create both login via user/pass and cert for variety.
#Make sure we are in the right folder
cd /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/
#Create a Regular User Cert
docker exec -it takserver-"$(cat tak/version.txt)" bash -c "cd /opt/tak/certs && ./makeCert.sh client takuser"
#Create another user cert that we will turn into an admin
docker exec -it takserver-"$(cat tak/version.txt)" bash -c "cd /opt/tak/certs && ./makeCert.sh client TAKADMIN"
#Now Get the TakServer ContainerID
docker ps
#Issue the following command, replacing "TAKADMIN" with your intended admin user you created above.
docker exec -it CONTAINERIDHERE bash -c "openssl x509 -noout -fingerprint -md5 -inform pem -in /opt/tak/certs/files/TAKADMIN.pem | grep -oP 'MD5 Fingerprint=\K.*'"
#This will print out a fingerprint, we will use it in the next command
#Give our admin user admin access Fill in the tak server container ID, and fingerpint form above. Also don't forget to change your user.
docker exec -it CONTAINERIDHERE bash -c 'java -jar /opt/tak/utils/UserManager.jar usermod -A -f 2E:C8:A0:27:F4:85:80:A9:62:9B:7A:3C:BE:DA:8A:6B TAKADMIN'
#Create a user/pass admin login account(no Cert Needed)
docker exec CONTAINERIDHERE bash -c "cd /opt/tak/ && java -jar /opt/tak/utils/UserManager.jar usermod -A -p COMPLEXPASSHERE SUERHERE"
#create a user/pass user account(no CertNeeded)
docker exec CONTAINERIDHERE bash -c "cd /opt/tak/ && java -jar /opt/tak/utils/UserManager.jar usermod -p COMPLEXPASSHERE SUERHERE"
Now that’s over, we can restart the TAKServer container so it takes effect.
docker exec -d takserver-"$(cat tak/version.txt)" bash -c "cd /opt/tak/ && ./configureInDocker.sh"
Open Firewall Ports
Run the following commands to open the firewall for the TAK server as well as federation. The firewall on your network/system bay be different.
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8089/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8444/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8446/tcp --permanent
sudo firewall-cmd --zone=public --add-port=9000/tcp --permanent
sudo firewall-cmd --zone=public --add-port=9001/tcp --permanent
Import Your Client Certificates
You need to grab the “p12″ files for the users you intend to distribute or login with, as well as the Truststore Cetificate p12 file. These can be found in:” /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/certs/files/”.
You can copy the files from your server to your workstation using scp, as we did with uploading the software.
Copy them to your WorkStation
#Copy the certs to a new folder at /home/takusr/certs
mkdir /home/takusr/certs
sudo cp /home/takusr/taksrv/takserver-docker-4.9-RELEASE-46/tak/certs/files/*.p12 /home/takusr/certs
sudo chmod 777 /home/takusr/certs/*
#Issued from your workstation
scp takusr@SERVERIP:~/certs/*.p12 .
Transfer them onto the system you would like to access your TAK server with.
The user “p12” files are imported into the client certificate in the application you are using such as WinTak. The TrustStore Certificate “p12” file is to be used as the server certificate in your application.
The password unless changed for your certs is “atakatak”
Configure your TAK Client use connect to the server IP via port 8089.
If using the webrowser with your certificates, navigate to: https://yourserverip:8443/
If using the webrowser to access with a login/pass navigate to https://yourserverip:8446/ OR http://yourserverip:8080/
If accessing via the web browser, you can double click these files and install them onto your computer.
Adding a LetsEncrypt Certificate
This assumes you have the fullchain.pem from LetsEncrypt in the current directory
Use atakatak as the password for everything and replace “tak.penley.io” with your own domain name.
#Create jks from letsencrypt cert chain:
sudo openssl pkcs12 -export -in fullchain2.pem -inkey privkey2.pem -out takserver-le.p12 -name tak.penley.io
sudo openssl pkcs12 -info -in takserver-le.p12
sudo keytool -importkeystore -destkeystore takserver-le.jks -srckeystore takserver-le.p12 -srcstoretype pkcs12
Transfer takserver-le.jks to your certs/files fodler on the TAK server.
Change permissions to your takusr
chown -R takusr:takusr takserver-le.jks
Stop Tak Server container
docker stop containerhere
Remove CoreConfig.xml from the tak folder:
rm CoreConfig.xml
Edit CoreConfig.Example.xml
Make your port 8446 line looks like the following:
<connector port="8446" clientAuth="false" _name="LetsEncrypt" keystore="JKS" keystoreFile="/opt/tak/certs/files/takserver-le.jks" keystorePass="atakatak"/>
Make sure your port 8089 line looks like the following:
<input _name="cassl" protocol="tls" port="8089" auth="x509"/>
For certificate signing, use the following:
<certificateSigning CA="TAKServer">
<certificateConfig>
<nameEntries>
<nameEntry name="O" value="PENTAK"/>
<nameEntry name="OU" value="FATS"/>
</nameEntries>
</certificateConfig>
<TAKServerCAConfig
keystore="JKS"
keystoreFile="certs/files/PENTAK-ISSUING-CA-signing.jks"
keystorePass="atakatak"
validityDays="30"
signatureAlg="SHA256WithRSA" />
</certificateSigning>