Skip to content

Instantly share code, notes, and snippets.

@tonyclemmey
Last active November 1, 2022 14:13
Show Gist options
  • Save tonyclemmey/f23e7e3c1311be3ec831dd2593ad0a2a to your computer and use it in GitHub Desktop.
Save tonyclemmey/f23e7e3c1311be3ec831dd2593ad0a2a to your computer and use it in GitHub Desktop.
MongoDB Setup
#!/bin/bash
# ===================================
# ########## Bash Colours ###########
# ===================================
NC='\033[31;0m' # no colors or formatting
RED='\033[0;31;1m' # print text in bold Red
GRE='\033[0;32;1m' # print text in bold Green
YEL='\033[0;33;1m' # print text in bold Yellow
BLU='\033[0;34;1m' # print text in bold Blue
PUR='\033[0;35;1m' # print text in bold Purple
CYA='\033[0;36;1m' # print text in bold Cyan
GRA='\033[0;37;1m' # print text in bold Gray
# ===================================
# ######## Require root user ########
# ===================================
if [[ $UID -ne 0 ]]; then
echo -e "${RED}This script needs to be run as root (with sudo).${NC}"
exit 1
fi
# ===================================
# ######## AppArmor MongoDB ########
# ===================================
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Enabling AppArmor for MongoDB Replica Sets${NC}"
echo -e "${YEL}===================================${NC}"
# https://severalnines.com/blog/how-configure-apparmor-mongodb-replica-sets/
# https://severalnines86.rssing.com/chan-56164748/article281.html
if sudo systemctl status apparmor | grep 'active'; then
sudo touch /etc/apparmor.d/usr.bin.mongod
sudo tee /etc/apparmor.d/usr.bin.mongod <<EOF
#include <tunables/global>
/usr/sbin/mongod {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/user-tmp>
#include <abstractions/winbind>
# Allow system resource access
/sys/devices/system/cpu/ r,
/sys/devices/system/node/ r,
/sys/devices/system/node/** r,
/proc/*/status r,
capability sys_resource,
capability dac_override,
capability setuid,
capability setgid,
capability sys_nice,
# Allow network access
network tcp,
/etc/hosts.allow r,
/etc/hosts.deny r,
# Allow config access
/etc/mongod.conf r,
# Allow pid, socket, socket lock file access
/var/run/mongod.pid rw,
# Allow systemd notify messages
/{,var/}run/systemd/notify w,
# Allow execution of server binary
/usr/sbin/mongo mr,
/usr/sbin/mongod mr,
/usr/sbin/mongos mr,
/usr/sbin/mongotop mr,
/usr/sbin/mongorestore mr,
/usr/sbin/mongoimport mr,
/usr/sbin/mongofiles mr,
/usr/sbin/mongodump mr,
# Allow data files dir access
/data/db/ r,
/data/db/** rwk,
/var/lib/mongodb/ r,
/var/lib/mongodb/** rwk,
# Allow log file access
/var/log/mongodb/ r,
/var/log/mongodb/** rw,
# Allow key files dir access
/var/lib/mongodb/keys/ r,
/var/lib/mongodb/keys/** r,
# Allow access to openssl config
/etc/mongo-cluster.key r,
# Site-specific additions and overrides. See local/README for details.
}
EOF
sudo aa-enforce /etc/apparmor.d/usr.bin.mongod
sudo systemctl restart apparmor
sudo apparmor_status
fi
#!/bin/bash
# ===================================
# ########## Bash Colours ###########
# ===================================
NC='\033[31;0m' # no colors or formatting
RED='\033[0;31;1m' # print text in bold Red
GRE='\033[0;32;1m' # print text in bold Green
YEL='\033[0;33;1m' # print text in bold Yellow
BLU='\033[0;34;1m' # print text in bold Blue
PUR='\033[0;35;1m' # print text in bold Purple
CYA='\033[0;36;1m' # print text in bold Cyan
GRA='\033[0;37;1m' # print text in bold Gray
# ===================================
# ######## ENV Variables ############
# ===================================
DISK_DATA='/dev/sdc'
# ===================================
# ######## Require root user ########
# ===================================
if [[ $UID -ne 0 ]]; then
echo -e "${RED}This script needs to be run as root (with sudo).${NC}"
exit 1
fi
# ===================================
# ######## Setup Data Disk ##########
# ===================================
BACKUP_SUFFIX=$(date +"%Y-%m-%d_%H-%M-%S")
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Creating and formating the new data partition${NC}"
echo -e "${YEL}===================================${NC}"
sudo /sbin/parted "${DISK_DATA}" mklabel gpt --script
sudo /sbin/parted "${DISK_DATA}" mkpart primary ext4 0% 100% --script
sudo /sbin/parted "${DISK_DATA}" print --script
echo "y" | sudo mkfs.ext4 "${DISK_DATA}1"
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Grabbing UUID for the new home partition${NC}"
echo -e "${YEL}===================================${NC}"
# @ link https://stackoverflow.com/questions/13565658/right-tool-to-filter-the-uuid-from-the-output-of-blkid-program-using-grep-cut
DATA_UUID=$(blkid -s UUID -o value "${DISK_DATA}1")
echo -e "${GRE}${DATA_UUID}${NC}"
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Updating fstab with the new data partition${NC}"
echo -e "${YEL}===================================${NC}"
sudo cp /etc/fstab /etc/fstab_backup-$BACKUP_SUFFIX
sudo diff /etc/fstab /etc/fstab_backup-$BACKUP_SUFFIX
sudo tee -a /etc/fstab <<EOF
UUID=${DATA_UUID} /data ext4 defaults 0 2
EOF
echo -e "${GRE}See changes made to /etc/fstab${NC}"
sudo diff /etc/fstab /etc/fstab_backup-$BACKUP_SUFFIX
sudo mkdir -p /data
sudo mkdir -p /data/db
sudo mount -a
#!/bin/bash
# ===================================
# ########## Bash Colours ###########
# ===================================
NC='\033[31;0m' # no colors or formatting
RED='\033[0;31;1m' # print text in bold Red
GRE='\033[0;32;1m' # print text in bold Green
YEL='\033[0;33;1m' # print text in bold Yellow
BLU='\033[0;34;1m' # print text in bold Blue
PUR='\033[0;35;1m' # print text in bold Purple
CYA='\033[0;36;1m' # print text in bold Cyan
GRA='\033[0;37;1m' # print text in bold Gray
# ===================================
# ######## ENV Variables ############
# ===================================
# mongodb
MONGODB_PORT='27017/tcp'
# ===================================
# ######## Require root user ########
# ===================================
if [[ $UID -ne 0 ]]; then
echo -e "${RED}This script needs to be run as root (with sudo).${NC}"
exit 1
fi
# ===================================
# ######## UFW allow MongoDB ########
# ===================================
if sudo ufw status | grep 'active'; then
sudo ufw allow $MONGODB_PORT
sudo ufw reload
echo -e "${GRE}Firewall Status${NC}"
sudo ufw status numbered
fi
#!/bin/bash
# ===================================
# ########## Bash Colours ###########
# ===================================
NC='\033[31;0m' # no colors or formatting
RED='\033[0;31;1m' # print text in bold Red
GRE='\033[0;32;1m' # print text in bold Green
YEL='\033[0;33;1m' # print text in bold Yellow
BLU='\033[0;34;1m' # print text in bold Blue
PUR='\033[0;35;1m' # print text in bold Purple
CYA='\033[0;36;1m' # print text in bold Cyan
GRA='\033[0;37;1m' # print text in bold Gray
# ===================================
# ######## ENV Variables ############
# ===================================
# MongoDB Cluster IPs
NODE_1_IP='192.168.200.140'
NODE_2_IP='192.168.200.141'
NODE_3_IP='192.168.200.142'
# MongoDB Cluster Hostnames
NODE_1_HOSTNAME='mongodb1.tcdesignio.co.uk'
NODE_2_HOSTNAME='mongodb2.tcdesignio.co.uk'
NODE_3_HOSTNAME='mongodb3.tcdesignio.co.uk'
# MongoDB Cluster ReplicaSet Name
REPLICA_SET_NAME='rs0'
# MongoDB Package/Edition ( mongodb-enterprise, mongodb-org )
MONGODB_PACKAGE='mongodb-enterprise'
# MongoDB Version ( 6.0, 5.0, 4.4... )
MONGODB_VERSION='5.0'
# MongoDB Repository URL
if [ $MONGODB_PACKAGE = 'mongodb-enterprise' ]; then
MONGODB_REPOSITORY='https://repo.mongodb.com/apt/ubuntu'
MONGODB_PGP_KEY="https://pgp.mongodb.com/server-$MONGODB_VERSION.asc"
elif [ $MONGODB_PACKAGE = 'mongodb-org' ]; then
MONGODB_REPOSITORY='https://repo.mongodb.org/apt/ubuntu'
MONGODB_PGP_KEY="https://www.mongodb.org/static/pgp/server-$MONGODB_VERSION.asc"
fi
# MongoDB Storage DB Path
MONGODB_STORAGE_DB_PATH='/data/db'
# MongoDB Accounts
ROOT_USERNAME='mongo-root'
ROOT_PASSWORD='password'
ADMIN_USERNAME='mongo-admin'
ADMIN_PASSWORD='password'
CLUSTER_ADMIN_USERNAME='mongo-cluster'
CLUSTER_ADMIN_PASSWORD='password'
# Current Server IP (https://stackoverflow.com/questions/21336126/)
# SERVER_IP=$(vagrant ssh -c "hostname -I | cut -d' ' -f2" 2>/dev/null)
SERVER_IP=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
# Override environment variables by adding them to your ~/.bash_profile, ~/.bashrc, or equivalent
# export VARIABLE=value
if [[ -f "$HOME/.bash_profile" ]]; then
source $HOME/.bash_profile
fi
# ===================================
# ######## Require root user ########
# ===================================
if [[ $UID -ne 0 ]]; then
echo -e "${RED}This script needs to be run as root (with sudo).${NC}"
exit 1
fi
# ===================================
# Removing previously installed MongoDB
# ===================================
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Removing previously installed MongoDB${NC}"
echo -e "${YEL}===================================${NC}"
sudo systemctl stop mongod
sudo apt-get purge mongodb* -y
sudo apt-get remove mongodb* -y
sudo rm -rf /usr/share/keyrings/mongodb*.asc
sudo rm -rf /etc/apt/sources.list.d/mongodb*.list
sudo rm -rf /var/log/mongodb*
sudo rm -rf /var/lib/mongodb*
sudo rm -rf /etc/mongod*
sudo apt-get update -y
# ===================================
# Install - https://www.mongodb.com/docs/manual/tutorial/install-mongodb-enterprise-on-ubuntu/
# ===================================
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Installing ${MONGODB_PACKAGE}-${MONGODB_VERSION}${NC}"
echo -e "${YEL}===================================${NC}"
sudo wget $MONGODB_PGP_KEY \
-qO /usr/share/keyrings/mongodb-server-$MONGODB_VERSION.asc
sudo tee /etc/apt/sources.list.d/$MONGODB_PACKAGE-$MONGODB_VERSION.list << EOF
deb [ arch=amd64,arm64 trusted=yes signed-by=/usr/share/keyrings/mongodb-server-$MONGODB_VERSION.asc ] $MONGODB_REPOSITORY focal/$MONGODB_PACKAGE/$MONGODB_VERSION multiverse
EOF
sudo apt-get update -y
sudo apt-get install $MONGODB_PACKAGE -y
sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod --no-pager
mongod --version
# ===================================
# Configure - https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/
# ===================================
# set permissions for MongoDB storage path
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Setting permissions on ${MONGODB_STORAGE_DB_PATH}${NC}"
echo -e "${YEL}===================================${NC}"
sudo mkdir -p $MONGODB_STORAGE_DB_PATH
sudo chown -R mongodb:mongodb $MONGODB_STORAGE_DB_PATH
sudo chmod 0755 $MONGODB_STORAGE_DB_PATH
# Add MongoDB Cluster IPs to Hosts file
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Updating hosts file${NC}"
echo -e "${YEL}===================================${NC}"
sudo tee -a /etc/hosts <<EOF
# MongoDB
$NODE_1_IP $NODE_1_HOSTNAME
$NODE_2_IP $NODE_2_HOSTNAME
$NODE_3_IP $NODE_3_HOSTNAME
EOF
# Set Bind Hostname
if [[ $SERVER_IP = $NODE_1_IP ]]; then
BIND_HOSTNAME=$NODE_1_HOSTNAME
elif [[ $SERVER_IP = $NODE_2_IP ]]; then
BIND_HOSTNAME=$NODE_2_HOSTNAME
elif [[ $SERVER_IP = $NODE_3_IP ]]; then
BIND_HOSTNAME=$NODE_3_HOSTNAME
fi
# Add keyfile
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Adding authentication keyfile${NC}"
echo -e "${YEL}===================================${NC}"
sudo mkdir -p /var/lib/mongodb/keys/
sudo touch /var/lib/mongodb/keys/mongodb_auth_key
# sudo openssl rand -base64 756 > /var/lib/mongodb/keys/mongodb_auth_key
sudo tee /var/lib/mongodb/keys/mongodb_auth_key <<EOF
6JiCr9tzIZEAH2CGNLSi3crki2jWW2axP6d/niQ09ExYuDnTFrqOAJi0tIgj9T2U
osUkGqtZyGG5oKqQP8vmRdsvL8qyJKb9MzeclEpfVQ2nbH7BrLeL+MWm9mq2gVjf
NW764csiI8y9cGZ7ZdVCFjiW7kOPKmkTkQyM+2JcP7pjZ916Xzd7kupdIifL+Rd/
fhArkjUh5ioIPP5PS00c9lXt3s8x3ZHqV5GZDWeBqUdgdCBvxqIXT0RUHSLUB7NT
0yrgLhmNO9/qq/rlsOVz87kaBgRIq4KL50FVwFdXHalKiqDoAIwlgNtahPaGKV+w
JY6rwhA9US3RtkJOLco6PIUTq5xqjsM7zMWQZFnF75JKl3r4/K363qRdOzygjvXK
VVYpJNUH4IT7XY05256/MV/E3o66jniGvey5aHXhqElaZWqe3Z0AqUJ5F5p2K+gV
jbekhecNh5MNDe2OSbglz2RPpJC3rh+R6vzAFxeiiK0mvpKvNWQTmo3ebdTq9llq
El+LvNMz2MYhBHfRWVgsaTrAhHVt1jV4cN/mVZ4My2aYCv9cmQ7Qu4n1zVvhnRdi
7l34+Bw3GERM1V/D+crkI5aYKuZckr0k3GaoAOPH4IZSK8LMlVB2h+38p+nlm5rc
q35lByYVaTWbcEIAHZ4SjENXqTFMfCwPxLRckxU1CG1mcqDGip984ciTwrg2EHqo
btkKErnKEIl2UK3aFiODcuvakcwsOP67GaCnAzYM6BG0zFKfV37MUEWH8y2hTfFp
2qE9cHICs29D3e+2dY7UaPSvhNjm+Dp+UB3SEJIcYr+u5bL6hJoYmbKCbAf5Enif
yKGNoPs5vriFgfTmpeu6YUkPTHeVaUpLLy80aJWn2iq9TQYN04GY5uyLdfHrRjOR
5IdU5qSya/gb5zDKoiW3D4BQ7uYTUXDOOVOHAUEk4JDl7sWvS5pHFoEKYTG12KE+
xQXqJddJglICw+UTBMMbyyXKNn36z4ec3veZQaSPG0Tla+WL
EOF
sudo chown -R mongodb:mongodb /var/lib/mongodb/keys/mongodb_auth_key
sudo chmod 600 /var/lib/mongodb/keys/mongodb_auth_key
# setup config
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Configuring mongod.conf${NC}"
echo -e "${YEL}===================================${NC}"
sudo mkdir -p /etc/mongodb
sudo mv /etc/mongod.conf /etc/mongodb/mongod.conf_backup-$(date +"%Y-%m-%d_%H-%M-%S")
sudo tee /etc/mongod.conf <<EOF
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: $MONGODB_STORAGE_DB_PATH
journal:
enabled: true
# engine:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# network interfaces
net:
port: 27017
bindIp: localhost,$BIND_HOSTNAME
# how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo
security:
authorization: enabled
keyFile: /var/lib/mongodb/keys/mongodb_auth_key
#transitionToAuth: true
#operationProfiling:
replication:
replSetName: $REPLICA_SET_NAME
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
EOF
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Restarting & Checking Status${NC}"
echo -e "${YEL}===================================${NC}"
sudo systemctl restart mongod
sudo systemctl status mongod --no-pager
# MongoDB Master Node
if [[ $SERVER_IP = $NODE_1_IP ]]; then
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Disabling Authentication on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo sed -i 's/authorization: enabled/authorization: disabled/' /etc/mongod.conf
sudo sed -i 's/#transitionToAuth: true/transitionToAuth: true/' /etc/mongod.conf
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Restarting & Checking Status on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo systemctl restart mongod
sudo systemctl status mongod --no-pager
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Initiating the Replica Set on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo tee mongo_rs_initiate.js <<EOF
rs.initiate(
{
_id: "$REPLICA_SET_NAME",
members: [
{ _id: 0, host: "$NODE_1_HOSTNAME:27017", priority: 10 },
{ _id: 1, host: "$NODE_2_HOSTNAME:27017", priority: 4 },
{ _id: 2, host: "$NODE_3_HOSTNAME:27017", priority: 1 }
]
}
)
EOF
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--file mongo_rs_initiate.js
sleep 1m 30s
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--eval 'printjson(rs.conf());' \
--eval 'printjson(rs.status());'
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Creating Root User on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo tee mongo_add_root_user.js <<EOF
db = db.getSiblingDB("admin");
db.createUser(
{
user: "$ROOT_USERNAME",
pwd: "$ROOT_PASSWORD",
roles: [{ role: "root", db: "admin" }]
}
);
EOF
mongosh "mongodb://$NODE_1_HOSTNAME:27017" --file mongo_add_root_user.js
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--eval 'use admin' \
--eval 'printjson(db.getUsers());'
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Creating Admin User on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo tee mongo_add_admin_user.js <<EOF
db = db.getSiblingDB("admin");
db.createUser(
{
user: "$ADMIN_USERNAME",
pwd: "$ADMIN_PASSWORD",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
);
EOF
mongosh "mongodb://$NODE_1_HOSTNAME:27017" --file mongo_add_admin_user.js
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--eval 'use admin' \
--eval 'printjson(db.getUsers());'
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Enforcing Authentication on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo sed -i 's/authorization: disabled/authorization: enabled/' /etc/mongod.conf
sudo sed -i 's/transitionToAuth: true/#transitionToAuth: true/' /etc/mongod.conf
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Restarting & Checking Status on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo systemctl restart mongod
sudo systemctl status mongod --no-pager
echo -e "${YEL}===================================${NC}"
echo -e "${YEL}Creating ClusterAdmin User on Master Node${NC}"
echo -e "${YEL}===================================${NC}"
sudo tee mongo_add_cluster_user.js <<EOF
db = db.getSiblingDB("admin");
db.createUser(
{
user: "$CLUSTER_ADMIN_USERNAME",
pwd: "$CLUSTER_ADMIN_PASSWORD",
roles: [ { role : "clusterAdmin" , db : "admin" } ]
}
);
EOF
sleep 1m 30s
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--username "$ADMIN_USERNAME" \
--password "$ADMIN_PASSWORD" \
--authenticationDatabase "admin" \
--file mongo_add_cluster_user.js
mongosh "mongodb://$NODE_1_HOSTNAME:27017" \
--username "$ADMIN_USERNAME" \
--password "$ADMIN_PASSWORD" \
--authenticationDatabase "admin" \
--eval 'use admin' \
--eval 'printjson(db.getUsers());'
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment