Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1efd073

Browse files
committed
Production deployment using letsencrypt certs (facebookarchive#115)
* Production deployment using letsencrypt certs * Fixing problems with variables * Fixed error on development provision Sort of typo when development provision used * Using getopt to get provision.sh parameters * laguage-pack after apt-get update * Fixing travis file for new provisioning * Using custom unison location * Fixing issues from comments * Check arguments with a list * Normal color variable name and display code dirs
1 parent 14f8c0d commit 1efd073

5 files changed

Lines changed: 268 additions & 40 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ language: generic
44
sudo: required
55
dist: trusty
66

7-
install: ./extra/provision.sh dev $TRAVIS_BUILD_DIR $TRAVIS_BUILD_DIR
7+
install: ./extra/provision.sh -m dev -s $TRAVIS_BUILD_DIR -d $TRAVIS_BUILD_DIR
88

99
script: ./extra/run_tests.sh $TRAVIS_BUILD_DIR

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Note that if you don't want to use the Vagrant VM (not recommended), you can pro
4848
sudo apt-get install git
4949
git clone https://github.com/facebook/fbctf
5050
cd fbctf
51-
./extra/provision.sh dev $PWD
51+
./extra/provision.sh -m dev -s $PWD
5252
```
5353

5454
### Production
@@ -59,7 +59,7 @@ The target system needs to be 64 bit Ubuntu 14.04. Run the following commands:
5959
sudo apt-get install git
6060
git clone https://github.com/facebook/fbctf
6161
cd fbctf
62-
./extra/provision.sh prod $PWD
62+
./extra/provision.sh -m prod -s $PWD
6363
```
6464

6565
*Note*: Because this is a production environment, the password will be randomly generated when the provision script finishes. This ensures that you can't forget to change the default password after provisioning. Make sure to watch the very end of the provision script, as the password will be printed out. It will not be stored elsewhere, so either keep track of it or change it. In order to change the password, run the following command:
@@ -70,7 +70,11 @@ set_password new_password ctf ctf fbctf $PWD
7070

7171
This will set the password to 'new_password', assuming the database user/password is ctf/ctf and the database name is fbctf (these are the defaults).
7272

73-
The provision script will place the code in the `/var/www/fbctf` directory, install all dependencies, and start the server. In order to run in production mode, we require that you use SSL. The provision script will ask you for your SSL certificate's CSR and key files. More information on setting up SSL is specific in the next session, but note that if you are just testing out the platform and not running it production, you want to use the instructions listed in the Development section below, as this takes care generating certificates for you. We will support Let's Encrypt in the future.
73+
By default, the provision script will place the code in the `/var/www/fbctf` directory, install all dependencies, and start the server. In order to run in production mode, we require that you use SSL. You can choose between generating new self-signed, using your own or generate valid SSL certificates using [Let's Encrypt](https://letsencrypt.org/). The provision script uses [certbot](https://certbot.eff.org/) to assist with the generation of valid SSL certificates. Use the help to see all the available options with the command:
74+
75+
```
76+
./extra/provision -h
77+
```
7478

7579
Once you've provisioned the VM, go to the URL/IP of the server. Click the "Login" link at the top right, enter the admin credentials, and you'll be redirected to the admin page. Enter the credentials you received at the end of the provision script to log in.
7680

extra/lib.sh

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ function log() {
77
echo "[+] $1"
88
}
99

10+
function error_log() {
11+
RED='\033[0;31m'
12+
NORMAL='\033[0m'
13+
echo "${RED} [!] $1 ${NORMAL}"
14+
}
15+
16+
function ok_log() {
17+
GREEN='\033[0;32m'
18+
NORMAL='\033[0m'
19+
echo "${GREEN} [+] $1 ${NORMAL}"
20+
}
21+
22+
function dl() {
23+
local __url=$1
24+
local __dest=$2
25+
26+
if [ -n "$(which wget)" ]; then
27+
wget -q "$__url" -O "$__dest"
28+
else
29+
curl -s "$__url" -o "$__dest"
30+
fi
31+
}
32+
1033
function package() {
1134
if [[ -n "$(dpkg --get-selections | grep $1)" ]]; then
1235
log "$1 is already installed. skipping."
@@ -72,32 +95,94 @@ function run_grunt() {
7295
fi
7396
}
7497

98+
function self_signed_cert() {
99+
local __csr="/etc/nginx/certs/dev.csr"
100+
local __devcert=$1
101+
local __devkey=$2
102+
103+
sudo openssl req -nodes -newkey rsa:2048 -keyout "$__devkey" -out "$__csr" -subj "/O=Facebook CTF"
104+
sudo openssl x509 -req -days 365 -in "$__csr" -signkey "$__devkey" -out "$__devcert"
105+
}
106+
107+
function letsencrypt_cert() {
108+
local __email=$3
109+
local __domain=$4
110+
111+
sudo dl "https://dl.eff.org/certbot-auto" /usr/bin/certbot-auto
112+
sudo chmod a+x /usr/bin/certbot-auto
113+
114+
if [[ $__email == "none" ]]; then
115+
read -p ' -> What is the email for the SSL Certificate recovery? ' __myemail
116+
else
117+
__myemail=$__email
118+
fi
119+
if [[ $__domain == "none" ]]; then
120+
read -p ' -> What is the domain for the SSL Certificate? ' __mydomain
121+
else
122+
__mydomain=$__domain
123+
fi
124+
125+
/usr/bin/certbot-auto certonly -n --standalone --standalone-supported-challenges tls-sni-01 -m "$__myemail" -d "$__mydomain"
126+
sudo ln -s "/etc/letsencrypt/live/$__mydomain/cert.pem" "$1"
127+
sudo ln -s "/etc/letsencrypt/live/$__mydomain/privkey.pem" "$2"
128+
}
129+
130+
function own_cert() {
131+
local __owncert=$1
132+
local __ownkey=$2
133+
134+
read -p ' -> SSL Certificate file location? ' __mycert
135+
read -p ' -> SSL Key Certificate file location? ' __mykey
136+
sudo cp "$__mycert" "$__owncert"
137+
sudo cp "$__mykey" "$__ownkey"
138+
}
139+
75140
function install_nginx() {
76141
local __path=$1
77142
local __mode=$2
143+
local __certs=$3
144+
local __email=$4
145+
local __domain=$5
146+
147+
local __certs_path="/etc/nginx/certs"
78148

79149
package nginx
80150

81151
log "Deploying certificates"
82-
sudo mkdir -p /etc/nginx/certs
152+
sudo mkdir -p "$__certs_path"
83153

84154
if [[ $__mode = "dev" ]]; then
85-
__csr="/etc/nginx/certs/dev.csr"
86-
__cert="/etc/nginx/certs/dev.crt"
87-
__key="/etc/nginx/certs/dev.key"
88-
sudo openssl req -nodes -newkey rsa:2048 -keyout "$__key" -out "$__csr" -subj "/O=Facebook CTF"
89-
sudo openssl x509 -req -days 365 -in "$__csr" -signkey "$__key" -out "$__cert"
155+
local __cert="$__certs_path/dev.crt"
156+
local __key="$__certs_path/dev.key"
157+
self_signed_cert "$__cert" "$__key"
90158
elif [[ $__mode = "prod" ]]; then
91-
__cert="/etc/nginx/certs/fbctf.csr"
92-
__key="/etc/nginx/certs/fbctf.key"
93-
read -p ' -> SSL Certificate file location? ' __mycert
94-
read -p ' -> SSL Key Certificate file location? ' __mykey
95-
sudo cp "$__mycert" "$__cert"
96-
sudo cp "$__mykey" "$__key"
159+
local __cert="$__certs_path/fbctf.crt"
160+
local __key="$__certs_path/fbctf.key"
161+
case "$__certs" in
162+
self)
163+
self_signed_cert "$__cert" "$__key"
164+
break
165+
;;
166+
own)
167+
own_cert "$__cert" "$__key"
168+
break
169+
;;
170+
certbot)
171+
letsencrypt_cert "$__cert" "$__key" "$__email" "$__domain"
172+
break
173+
;;
174+
*)
175+
error_log "Unrecognized type of certificate"
176+
exit 1
177+
;;
178+
esac
97179
fi
180+
98181
__dhparam="/etc/nginx/certs/dhparam.pem"
99182
sudo openssl dhparam -out "$__dhparam" 2048
183+
100184
cat "$__path/extra/nginx.conf" | sed "s|CTFPATH|$__path/src|g" | sed "s|CER_FILE|$__cert|g" | sed "s|KEY_FILE|$__key|g" | sed "s|DHPARAM_FILE|$__dhparam|g" | sudo tee /etc/nginx/sites-available/fbctf.conf
185+
101186
sudo rm /etc/nginx/sites-enabled/default
102187
sudo ln -s /etc/nginx/sites-available/fbctf.conf /etc/nginx/sites-enabled/fbctf.conf
103188

@@ -187,17 +272,17 @@ function import_empty_db() {
187272
}
188273

189274
function set_password() {
190-
local __admin_pwd=$1
191-
local __user=$2
192-
local __db_pwd=$3
193-
local __db=$4
194-
local __path=$5
275+
local __admin_pwd=$1
276+
local __user=$2
277+
local __db_pwd=$3
278+
local __db=$4
279+
local __path=$5
195280

196-
HASH=$(hhvm -f "$__path/extra/hash.php" "$__admin_pwd")
281+
HASH=$(hhvm -f "$__path/extra/hash.php" "$__admin_pwd")
197282

198-
# First try to delete the existing admin user
199-
mysql -u "$__user" --password="$__db_pwd" "$__db" -e "DELETE FROM teams WHERE name='admin' AND admin=1"
283+
# First try to delete the existing admin user
284+
mysql -u "$__user" --password="$__db_pwd" "$__db" -e "DELETE FROM teams WHERE name='admin' AND admin=1"
200285

201-
# Then insert the new admin user with ID 1 (just as a convention, we shouldn't rely on this in the code)
202-
mysql -u "$__user" --password="$__db_pwd" "$__db" -e "INSERT INTO teams (id, name, password_hash, admin, protected, logo, created_ts) VALUES (1, 'admin', '$HASH', 1, 1, 'admin', NOW());"
286+
# Then insert the new admin user with ID 1 (just as a convention, we shouldn't rely on this in the code)
287+
mysql -u "$__user" --password="$__db_pwd" "$__db" -e "INSERT INTO teams (id, name, password_hash, admin, protected, logo, created_ts) VALUES (1, 'admin', '$HASH', 1, 1, 'admin', NOW());"
203288
}

0 commit comments

Comments
 (0)