Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions docs/dhis2-set-credential.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# dhis2-set-credential
Security of the servers and services is a priority. We need to set username and password credentials for the munin monitoring service and the Glowroot APM tool on each instance we have created to prevent unwanted users from accessing sensitive or critical data.
Credentials will be set once we install the monitor container or a DHIS2 instance with Glowroot APM or can be reset by the user later.

## Automatic execution
The dhis2-set-credential service will run once the monitor container is installed or when a DHIS2 instance with Glowroot APM is created. The user will be prompted to type in the desired password and otherwise it will be randomly generated.
```
SET <SERVICE> CREDENTIALS
====================
Do you want to add the password manually for the user admin in the service <SERVICE>? (If not, password will be generated randomly)
1) Yes
2) No
```
Password will be shown to the user
```
Credentials have been set
=================
Service: monitor (munin)
Username: admin
Password: XXXXX
```

## Manual execution
The user will be able to reset the password of a service by running the service script dhis2-set-credentials.
```
usage: dhis2-set-credential <SERVICE>
Valid services are: <available services will be shown>
```

For example, to change the Glowroot APM admin password for the *hmis* DHIS2 instance, the user has to run the command
```
sudo dhis2-set-credential hmis
```

The user will be prompted to type in the desired password and otherwise it will be randomly generated and password will be shown to the user.
```
SET hmis CREDENTIALS
====================
Do you want to add the password manually for the user admin in the service hmis? (If not, password will be generated randomly)
1) Yes
2) No
```

```
Credentials have been set
=================
Instance: hmis
Service: hmis-glowroot
Username: admin
Password: XXXXX
```

If the user wants to reset a Glowroot APM password, he will be notified that in order to set the password, the instance will be restarted and he will be prompted for confirmation. Otherwise, the password will not be set.
```
Instance hmis will be restarted. Are you sure do you want to continue?
1) Yes
2) No
```

This procedure will only change the admin password. The rest of roles or users created will remain.
3 changes: 2 additions & 1 deletion setup/configs/glowroot-admin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"users": [
{
"username": "anonymous",
"username": "admin",
"passwordHash": "PASSWORD",
"roles": [
"Administrator"
]
Expand Down
4 changes: 3 additions & 1 deletion setup/containers/munin_monitor
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ fi
sed -i '/tmpldir/s/^#//' $MUNINCONF

# Fix up Apache2
perl -pi -e "s|Require local|Require all granted|sig" $MUNINA2CONF
#perl -pi -e "s|Require local|Require all granted|sig" $MUNINA2CONF
perl -pi -e "s|Require local|AuthUserFile /etc/munin/.htpasswd\n Authtype Basic\n AuthName \"Munin\"\n Require valid-user\n Options FollowSymLinks SymLinksIfOwnerMatch|sig" $MUNINA2CONF
ln -s $MUNINA2CONF /etc/apache2/conf-available/munin.conf > /dev/null 2>&1
touch /etc/munin/.htpasswd
a2enconf munin.conf

#Also add hosts as required to the config file
Expand Down
17 changes: 14 additions & 3 deletions setup/containers/munin_monitor_postsetup
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
source parse_config.sh

# Check if monitor container already exists
lxc file pull monitor/etc/munin/.htpasswd /tmp/.htpasswd
CHECK_HTPASSWD=$(cat /tmp/.htpasswd)
if [[ $CHECK_HTPASSWD == "" ]];
then
dhis2-set-credential monitor
else
rm /tmp/.htpasswd
fi

if [[ $PROXY == "nginx" ]];
then
#if proxy is nginx ;
Expand Down Expand Up @@ -30,23 +40,24 @@ then
}
EOF
lxc file push /tmp/munin.conf proxy/etc/nginx/upstream/munin.conf
rm /tmp/munin.conf
rm /tmp/munin.conf

lxc exec proxy -- service nginx reload
elif [[ $PROXY == "apache2" ]];
then
#if proxy is apache2 ;
cat <<EOF > /tmp/munin
<Location /munin>
Require all granted
ProxyPass "http://${MUNIN_IP}/munin"
ProxyPassReverse "http://${MUNIN_IP}/munin"
</LOcation>
</Location>
EOF
lxc file push /tmp/munin proxy/etc/apache2/upstream/munin
rm /tmp/munin
lxc exec proxy -- service apache2 reload
else
echo "Error: Proxy type not supported"
exit 1
fi


31 changes: 4 additions & 27 deletions setup/containers/nginx_proxy_postsetup
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ echo "nginx setup running"
# performance.conf
####
cat <<EOF > /tmp/performance.conf
server_tokens off;
large_client_header_buffers 2 1k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
send_timeout 10;
send_timeout 10;
types_hash_max_size 2048;
client_max_body_size 20M;
client_body_timeout 10;
client_body_timeout 10;
client_header_timeout 10;
EOF

Expand Down Expand Up @@ -67,37 +69,12 @@ resolver 8.8.4.4 8.8.8.8 valid=300s ipv6=off;
resolver_timeout 10s;
EOF

####
# security.conf
####
cat <<EOF > /tmp/security.conf
# Referrer Policy
add_header Referrer-Policy "no-referrer";

# Avoid clickjacking attack
add_header X-Frame-Options "SAMEORIGIN" always;

# Enable Strict Transport Security (HSTS) for https;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Hide nginx server version
server_tokens off;

# Protect against MIME sniffing vulnerabilities
add_header X-Content-Type-Options "nosniff" always;

# X-XSS Protection
add_header X-XSS-Protection "1; mode=block" always;
EOF

lxc file push /tmp/performance.conf $NAME/etc/nginx/conf.d/performance.conf
rm /tmp/performance.conf
lxc file push /tmp/gzip.conf $NAME/etc/nginx/conf.d/gzip.conf
rm /tmp/gzip.conf
lxc file push /tmp/ssl.conf $NAME/etc/nginx/conf.d/ssl.conf
rm /tmp/ssl.conf
lxc file push /tmp/security.conf $NAME/etc/nginx/conf.d/security.conf
rm /tmp/security.conf

# Remove nginx references
lxc exec $NAME -- sed -i "s/nginx/webserver/g" /usr/share/nginx/html/index.html
Expand Down
12 changes: 9 additions & 3 deletions setup/create_containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ if [[ $UFW_STATUS == "inactive" ]]; then
echo "It is required to NAT connections to the proxy container."
echo "You just need to have a rule to allow ssh access. eg:"
echo " sudo ufw limit 22/tcp"
echo "then, 'sudo enable ufw'"
echo "then, 'sudo ufw enable'"
echo "Then you can try to run ./create_containers again"
exit 1
fi

# Make sure ufw is not blocking the lxd traffic
ufw allow in on lxdbr0
sudo ufw allow in on lxdbr0
sudo ufw allow out on lxdbr0

apt-get -y install unzip auditd jq
sudo apt-get -y install unzip auditd jq apache2-utils

# Parse json config file
source parse_config.sh
Expand All @@ -45,6 +45,12 @@ for CONTAINER in $CONTAINERS; do
IP=$(echo $CONTAINER | jq -r .ip)
TYPE=$(echo $CONTAINER | jq -r .type)

container_exist=$(lxc list -c n | grep $NAME)
if ! [ -z "$container_exist" ]; then
echo "Container $NAME already exist, skipping"
continue
fi

echo "Creating $NAME of type $TYPE"
lxc init ubuntu:$GUESTOS $NAME
lxc network attach $LXDBR $NAME eth0 eth0
Expand Down
5 changes: 5 additions & 0 deletions setup/delete_all.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env bash

CREDENTIALS_FILE=/usr/local/etc/dhis/.credentials.json

echo "Are you really sure you want to delete all containers"
select yn in "Yes" "No"; do
case $yn in
Expand All @@ -8,6 +10,9 @@ select yn in "Yes" "No"; do
esac
done

#Remove all credentials
jq 'del(.credentials[])' ${CREDENTIALS_FILE} > ${CREDENTIALS_FILE}.tmp && mv ${CREDENTIALS_FILE}.tmp ${CREDENTIALS_FILE}

for c in $( sudo lxc list --format csv -c n); do
echo "Deleting $c"
lxc delete --force $c
Expand Down
3 changes: 3 additions & 0 deletions setup/etc/.credentials.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"credentials": []
}
3 changes: 3 additions & 0 deletions setup/install_scripts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ for FILE in $(find etc/*); do
fi
done

# copy credentials file
cp etc/.credentials.json /usr/local/etc/dhis/

# copy glowroot-admin.json to /usr/local/etc/dhis/
if [ -f configs/glowroot-admin.json ];
then
Expand Down
2 changes: 2 additions & 0 deletions setup/parse_config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ PROXY_IP=$(echo $CONFIG | jq -r '.containers[] | select(.name=="proxy") | .ip')
MUNIN_IP=$(echo $CONFIG | jq -r '.containers[] | select(.name=="monitor") | .ip')
ENCDEVICE=$(echo $CONFIG | jq -r .encrypted_device)
ENVIRONMENT=$(echo $CONFIG |jq ".environment")
CREDENTIALS_FILE="/usr/local/etc/dhis/.credentials.json"

if [[ ! $ENVIRONMENT == "null" ]]; then
ENVVARS=$(echo $ENVIRONMENT | jq -c "to_entries[]")
fi
Expand Down
44 changes: 29 additions & 15 deletions setup/service/dhis2-create-instance
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,15 @@ then
lxc file push /tmp/tomcat9 $NAME/etc/default/tomcat9
lxc exec $NAME -- wget -P /opt https://github.com/glowroot/glowroot/releases/download/v0.13.6/glowroot-0.13.6-dist.zip
lxc exec $NAME -- unzip -o /opt/glowroot-0.13.6-dist.zip -d /opt
sed "s/XXXX/${NAME}/" $GLOWROOT_SETUP > /tmp/glowroot-admin.json
lxc file push /tmp/glowroot-admin.json $NAME/opt/glowroot/admin.json
lxc file push $GLOWROOT_SETUP $NAME/opt/glowroot/admin.json
lxc exec $NAME -- chown -R tomcat.tomcat /opt/

#Set credentials for glowroot
dhis2-set-credential ${NAME}

lxc exec $NAME ufw allow proto tcp from $PROXY_IP to any port 4000

rm /tmp/tomcat9
rm /tmp/glowroot-admin.json
else
lxc file push /usr/local/etc/dhis/tomcat_default $NAME/etc/default/tomcat9
fi
Expand Down Expand Up @@ -202,12 +204,18 @@ then
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_hide_header X-Frame-Options;
proxy_hide_header Strict-Transport-Security;
proxy_hide_header X-Content-Type-Options;
proxy_hide_header X-XSS-protection;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;

# Enable Strict Transport Security (HSTS) for https
proxy_set_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
# To mitigate the risk of clickjacking attacks
proxy_set_header X-Frame-Options "SAMEORIGIN";
# To prevent drive-by download attacks where a user agent is sniffing content types in responses
proxy_set_header X-Content-Type-Options "nosniff";
# To leverage browser-based protections against cross-site scripting
proxy_set_header X-Xss-Protection "1; mode=block";

proxy_hide_header X-Powered-By;
proxy_hide_header Server;

proxy_connect_timeout 480s;
proxy_read_timeout 480s;
Expand All @@ -234,12 +242,18 @@ EOF
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_hide_header X-Frame-Options;
proxy_hide_header Strict-Transport-Security;
proxy_hide_header X-Content-Type-Options;
proxy_hide_header X-XSS-protection;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;

# Enable Strict Transport Security (HSTS) for https
proxy_set_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
# To mitigate the risk of clickjacking attacks
proxy_set_header X-Frame-Options "SAMEORIGIN";
# To prevent drive-by download attacks where a user agent is sniffing content types in responses
proxy_set_header X-Content-Type-Options "nosniff";
# To leverage browser-based protections against cross-site scripting
proxy_set_header X-Xss-Protection "1; mode=block";

proxy_hide_header X-Powered-By;
proxy_hide_header Server;

proxy_connect_timeout 480s;
proxy_read_timeout 480s;
Expand Down
4 changes: 4 additions & 0 deletions setup/service/dhis2-delete-instance
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ PROG=`basename $0`

APM=$(cat /usr/local/etc/dhis/containers.json| jq -r .apm)
PROXY=$(cat /usr/local/etc/dhis/containers.json| jq -r .proxy)
CREDENTIALS_FILE="/usr/local/etc/dhis/.credentials.json"

###############################################################
usage() {
Expand Down Expand Up @@ -66,5 +67,8 @@ lxc delete $NAME
lxc exec ${DBCONTAINER} -- dropdb $NAME
lxc exec ${DBCONTAINER} -- dropuser $NAME

#Remove glowroot credentials
jq --arg name $NAME-glowroot 'del(.credentials[] | select(.name == $name))' ${CREDENTIALS_FILE} > ${CREDENTIALS_FILE}.tmp && mv ${CREDENTIALS_FILE}.tmp ${CREDENTIALS_FILE}

sudo sed -i "/.* $N$/d" /etc/hosts

6 changes: 3 additions & 3 deletions setup/service/dhis2-deploy-war
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ usage() {
echo " -h, --help Display this help message"
}

while getopts :l:fh opt;
while getopts :l:f:h opt;
do
case $opt in
f)
Expand Down Expand Up @@ -52,8 +52,8 @@ fi
INSTANCE=$1

# download war file if we don't have it
test -f $TEMPWAR || wget -O $TEMPWAR $SOURCE || exit 1
unzip -t -q $TEMPWAR || { echo "Corrupt war file: $TEMPWAR"; exit 1; }
test -f $TEMPWAR || wget -O $TEMPWAR $SOURCE || { rm $TEMPWAR; exit 1; }
unzip -t -q $TEMPWAR || { echo "Corrupt war file: $TEMPWAR"; rm $TEMPWAR; exit 1; }

lxc exec $1 -- service tomcat9 stop
# give it a chance to shutdown
Expand Down
Loading