Forráskód Böngészése

Added deferred panicLog.Close to prevent leaking resources; improvements to the ad-hoc deploy script

Michael Goldberger 9 éve
szülő
commit
55b2892dd8
2 módosított fájl, 126 hozzáadás és 100 törlés
  1. 124 100
      Server/deploy_ad-hoc_server.sh
  2. 2 0
      Server/main.go

+ 124 - 100
Server/deploy_ad-hoc_server.sh

@@ -1,9 +1,12 @@
 #!/bin/bash
 
-# Make sure the script is run as root user
+# Make sure the script is run as root user, or someone in the 'docker' group
 if [[ ${EUID} -ne 0 ]]; then
-  echo "This script must be run as root"
-  exit 1
+  id | grep -q "docker"
+  if [[ $? -ne 0 ]]; then
+    echo "This script must be run as root, or a user in the 'docker' group"
+    exit 1
+  fi
 fi
 
 usage () {
@@ -35,7 +38,11 @@ generate_temporary_credentials () {
 	ssh-keygen -t rsa -b 4096 -C "temp-psiphond-ad_hoc" -f psiphond-ad_hoc -N ""
 	PUBLIC_KEY=$(cat psiphond-ad_hoc.pub)
 
-	echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST cat >> $HOME/.ssh/authorized_keys
+  if [ $USER == "root" ]; then
+    echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST "cat >> /$USER/.ssh/authorized_keys"
+  else
+    echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST "cat >> /home/$USER/.ssh/authorized_keys"
+  fi
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -45,7 +52,12 @@ generate_temporary_credentials () {
 destroy_temporary_credentials () {
 	echo "..Removing the temporary key from the remote host"
 	PUBLIC_KEY=$(cat psiphond-ad_hoc.pub)
-  ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST sed -i '/temp-psiphond-ad_hoc/d' $HOME/.ssh/authorized_keys
+
+  if [ $USER == "root" ]; then
+    ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed -i '/temp-psiphond-ad_hoc/d' /$USER/.ssh/authorized_keys"
+  else
+    ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed -i '/temp-psiphond-ad_hoc/d' /home/$USER/.ssh/authorized_keys"
+  fi
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -112,15 +124,14 @@ save_image () {
 
 put_and_load_image () {
 	echo "..Copying '${ARCHIVE}' to '${HOST}:/tmp'"
-	scp -i psiphond-ad_hoc -o IdentitiesOnly=yes -P $PORT $ARCHIVE $USER@$HOST:/tmp/
+	scp -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -P $PORT $ARCHIVE $USER@$HOST:/tmp/
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
 	fi
 
 	echo "..Loading image into remote docker"
-  # Variable interpolation into the remote script doesn't always work as expected, use fixed paths here instead
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST zcat /tmp/psiphond-ad-hoc.tar.gz | docker load && rm /tmp/psiphond-ad-hoc.tar.gz
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "zcat /tmp/$ARCHIVE | docker load && rm /tmp/$ARCHIVE"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -129,7 +140,8 @@ put_and_load_image () {
 
 remove_image () {
 	echo "..Removing image from remote docker"
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST docker rmi ${CONTAINER_TAG}
+  # Single quotes prevents local substitution of variables
+  ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST 'docker rmi $(docker images -q psiphond/ad-hoc)'
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -137,10 +149,17 @@ remove_image () {
 }
 
 put_systemd_dropin () {
+  echo "..Creating ad-hoc environment variables file"
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed 's/DOCKER_CONTENT_TRUST=1/DOCKER_CONTENT_TRUST=0/' /opt/psiphon/psiphond/config/psiphond.env | sed '/CONTAINER_TAG=/d' > /opt/psiphon/psiphond/config/psiphond.env.adhoc"
+	if [ $? -ne 0 ]; then
+		echo "...Failed"
+		return 1
+	fi
+
 	echo "..Creating systemd unit drop-in"
 	cat <<- EOF > ad-hoc.conf
 	[Service]
-	Environment=DOCKER_CONTENT_TRUST=0
+	EnvironmentFile=/opt/psiphon/psiphond/config/psiphond.env.adhoc
 
 	# Clear previous pre-start command before setting new one
 	# Execute these commands prior to starting the service
@@ -151,17 +170,17 @@ put_systemd_dropin () {
 
 	# Clear previous start command before setting new one
 	ExecStart=
-	ExecStart=/usr/bin/docker run --rm $CONTAINER_PORT_STRING $CONTAINER_VOLUME_STRING $CONTAINER_ULIMIT_STRING $CONTAINER_SYSCTL_STRING --name %p-run ${CONTAINER_TAG}
+	ExecStart=/usr/bin/docker run --rm \$CONTAINER_PORT_STRING \$CONTAINER_VOLUME_STRING \$CONTAINER_ULIMIT_STRING \$CONTAINER_SYSCTL_STRING --name %p-run ${CONTAINER_TAG}
 	EOF
 
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST mkdir -p /etc/systemd/system/psiphond.service.d
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "mkdir -p /etc/systemd/system/psiphond.service.d"
 	echo "..Ensuring drop-in directory is available"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
 	fi
 
-	scp -i psiphond-ad_hoc -o IdentitiesOnly=yes -P $PORT ad-hoc.conf $USER@$HOST:/etc/systemd/system/psiphond.service.d/
+	scp -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -P $PORT ad-hoc.conf $USER@$HOST:/etc/systemd/system/psiphond.service.d/
 	echo "..Copying drop-in to remote host"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
@@ -173,7 +192,14 @@ put_systemd_dropin () {
 
 remove_systemd_dropin () {
 	echo "..Removing systemd unit drop-in"
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST [ ! -f /etc/systemd/system/psiphond.service.d/ad-hoc.conf ] || rm /etc/systemd/system/psiphond.service.d/ad-hoc.conf
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "[ ! -f /etc/systemd/system/psiphond.service.d/ad-hoc.conf ] || rm /etc/systemd/system/psiphond.service.d/ad-hoc.conf"
+	if [ $? -ne 0 ]; then
+		echo "...Failed"
+		return 1
+	fi
+
+  echo "..Removing ad-hoc environment variables file"
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "[ ! -f /opt/psiphon/psiphond/config/psiphond.env.adhoc ] || rm /opt/psiphon/psiphond/config/psiphond.env.adhoc"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -182,7 +208,7 @@ remove_systemd_dropin () {
 
 reload_systemd () {
 	echo "..Reloading systemd unit file cache"
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST systemctl daemon-reload
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "systemctl daemon-reload"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
@@ -191,13 +217,79 @@ reload_systemd () {
 
 restart_psiphond () {
 	echo "..Restarting the 'psiphond' service"
-	ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST systemctl restart psiphond
+	ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "systemctl restart psiphond"
 	if [ $? -ne 0 ]; then
 		echo "...Failed"
 		return 1
 	fi
 }
 
+install() {
+	docker_build_builder
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	docker_build_psiphond_binary
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	docker_build_psiphond_container
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	save_image
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	put_and_load_image
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	put_systemd_dropin
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	reload_systemd
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	restart_psiphond
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+}
+
+remove () {
+	remove_systemd_dropin
+	if [ $? -ne 0 ]; then
+		echo "...Failed, continuing removal steps. Drop-in file or ad-hoc environment file may still exist"
+	fi
+
+	reload_systemd
+	if [ $? -ne 0 ]; then
+		echo "...Failed, continuing removal steps. 'systemctl daemon-reload' may still be needed to restore previous functionality"
+	fi
+
+	restart_psiphond
+	if [ $? -ne 0 ]; then
+		echo "...Failed, continuing removal steps. The old 'psiphond' may still be running"
+	fi
+
+	remove_image
+	if [ $? -ne 0 ]; then
+		echo "...Final step failed, check for leftover images manually with 'docker images psiphond/ad-hoc', then use 'docker rmi' to remove them"
+    destroy_temporary_credentials
+		return 1
+	fi
+}
+
 # Locate and change to the directory containing the script
 BASE=$( cd "$(dirname "$0")" ; pwd -P )
 cd $BASE
@@ -276,8 +368,10 @@ echo " - Action: ${ACTION}"
 echo " - User: ${USER}"
 echo " - Host: ${HOST}"
 echo " - Port: ${PORT}"
-echo " - Containter Tag: ${CONTAINER_TAG}"
-echo " - Archive Name: ${ARCHIVE}"
+if [ $ACTION == "install" ]; then
+  echo " - Containter Tag: ${CONTAINER_TAG}"
+  echo " - Archive Name: ${ARCHIVE}"
+fi
 echo ""
 echo "Pausing 5 seconds to allow for ^C prior to starting"
 sleep 5
@@ -289,89 +383,19 @@ if [ $? -ne 0 ]; then
 fi
 
 if [ "${ACTION}" == "install" ]; then
-	docker_build_builder
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	docker_build_psiphond_binary
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	docker_build_psiphond_container
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	save_image
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	put_and_load_image
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	put_systemd_dropin
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	reload_systemd
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	restart_psiphond
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
+  install
+  if [ $? -ne 0 ]; then
+    echo "....Error during install, rolling back"
+    remove
+    if [ $? -ne 0 ]; then
+      echo "....Rollback failed"
+    fi
+  fi
 elif [ "${ACTION}" == "remove" ]; then
-	remove_systemd_dropin
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	reload_systemd
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	restart_psiphond
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
-
-	remove_image
-	if [ $? -ne 0 ]; then
-		echo "...Aborting"
-    destroy_temporary_credentials
-		exit 1
-	fi
+  remove
+  if [ $? -ne 0 ]; then
+    echo "...Rollback failed"
+  fi
 else
 	echo "Parameter validation passed, but action was not 'install' or 'remove', aborting"
 	exit 1

+ 2 - 0
Server/main.go

@@ -249,6 +249,8 @@ func panicHandler(output string) {
 				fmt.Printf("unable to set panic log output: %s\n%s\n", err, output)
 				os.Exit(1)
 			}
+			defer panicLog.Close()
+
 			jsonWriter = panicLog
 		} else {
 			jsonWriter = os.Stderr