├── LICENSE ├── README.md └── jss-in-a-box.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Richard Purves 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSS-In-A-Box 2 | 3 | ## The (almost) complete Jamf Pro JSS setup script 4 | ## http://www.richard-purves.com/?p=136 5 | 6 | ## Before we start, i'm planning to refactor the code and modularise a lot more functions as it's getting untidy in here. That'll be next big release, just not sure when. 7 | 8 | ### Introduction 9 | 10 | This is the (almost) complete setup script for JAMF Software's JSS server. It will perform the following tasks :- 11 | 12 | 1. Install and configure all the software packages required to run the JSS 13 | 2. Harden the server via software firewall and optional HTTPS certificates 14 | 3. Show all currently running JSS on the server 15 | 4. Create a new JSS and Database 16 | 5. Delete an existing JSS and Database 17 | 6. Dump a selected (or ALL) JSS database to a file 18 | 7. Upload a database file back into MySQL 19 | 8. Upgrade a single JSS install on the server 20 | 9. Upgrade ALL JSS installs on the server 21 | 10. (optional) Refresh Tomcat SSL certificate from [LetsEncrypt](http://letsencrypt.org) 22 | (The LetsEncrypt certificates are automatically renewed via a cron job. The same code can be invoked manually with this option) 23 | 11. Will now optimally configure Tomcat and MySQL (locally only) for number of instances, available ram etc etc. 24 | (this one was HARD to do) 25 | 26 | The only things it doesn't do are: 27 | 1) Set up anything to do with load balancing. That can be done inside the JSS itself. 28 | 2) Any remote server configuration with the sole exception of modifying remote databases. 29 | 3) Clustered server setup. 30 | 31 | ###### Oh, and NO SNEAKY using this on your CJA course! I've tipped off the JAMF instructors I know of! 32 | 33 | ### Getting started 34 | 35 | This assumes you have an either an Ubuntu 16.04 LTS or a RedHat 7.x server installed with openssh. 36 | This also assumes the server is properly configured to see the internet and has a properly set up DNS hostname. 37 | 38 | Please do NOT use Ubuntu's minimal iso install. This will miss out lots of key software and this script will fail. Use the "server" download instead. 39 | 40 | 1. Download the proper script depending on which Linux distribution you are using. 41 | 2. Edit the jss-in-a-box.sh script variables in line with your own security policies 42 | - Server admin username 43 | - Use LetsEncrypt (if this is set to FALSE, then the JSS will be set up without HTTPS) 44 | - SSL Domain name for the server 45 | - SSL E-mail address to register with the LetsEncrypt CA 46 | - SSL Keypass password 47 | - MySQL root password 48 | - MySQL server address 49 | - JSS database username 50 | - JSS database password 51 | 3. Edit the jss-in-a-box.sh script firewall settings. 52 | 4. scp the ROOT.war file supplied by JAMF to the server 53 | 5. scp the jss-in-a-box.sh script over to the server 54 | 6. Run the script with sudo. e.g. sudo ./jss-in-a-box.sh 55 | 7. Follow the options! (They are all disabled until no.1 is run successfully). 56 | 57 | You should, depending on server and internet speed have a fully functioning JSS running inside of an hour. Probably less. 58 | 59 | (Optional) Run the script with sudo ./jss-in-a-box.sh -h to get a help prompt. 60 | 61 | The instructional video below provides more details of operation. NOTE: This is of an earlier version but the info is still valid. 62 | 63 | ### Instructional Video 64 | 65 | JSS in a Box 66 | 67 | ### Software Installed 68 | 69 | * JSS 70 | * Curl (missing from Ubuntu) 71 | * Git (used purely for installing LetsEncrypt) 72 | * Unzip 73 | * Uncomplicated Firewall (Ubuntu) / FirewallD (Redhat) 74 | * OpenSSL 75 | * OpenVMTools 76 | * Oracle Java 8 77 | * Java Cryptography Extensions 78 | * Apache Tomcat 8.0x 79 | * MySQL Server 5.7 80 | * (optional) LetsEncrypt 81 | -------------------------------------------------------------------------------- /jss-in-a-box.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################################################## 4 | # 5 | # JSS in a Box 6 | # (aka a script to initialise, create, configure and delete JSS instances on a Ubuntu/RedHat server.) 7 | # (with apologies to Tom Bridge and https://github.com/tbridge/munki-in-a-box) 8 | # 9 | # The MIT License (MIT) 10 | # Copyright (c) 2015 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 13 | # software and associated documentation files (the "Software"), to deal in the Software 14 | # without restriction, including without limitation the rights to use, copy, modify, 15 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 16 | # persons to whom the Software is furnished to do so, subject to the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be included in all copies or 19 | # substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 22 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 24 | # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | # 27 | ########################################################################################## 28 | 29 | # Author : Richard Purves 30 | 31 | # Version 0.1 - 27th December 2015 - Initial Version 32 | # Version 0.2 - 28th December 2015 - Completed structure and initialisation code 33 | # Version 0.3 - 29th December 2015 - Completed all functions excluding database restoration 34 | # Version 0.4 - 30th December 2015 - Interactive Mode complete. Code for SSL present but untested. 35 | # Version 0.5 - 31st December 2015 - Implemented Ubuntu UFW rules for security 36 | # Implemented ability to talk to an external MySQL server. 37 | # Now creates/deletes JSS log files with modification to the JSS log4j file 38 | # Version 0.6 - 31st December 2015 - Extracts the DataBase.xml file from the provided ROOT.war file 39 | # Version 0.7 - 1st January 2016 - Code simplification and clean up. Was getting messy. 40 | # Can be invoked by parameter and skip the opening menu for specific functions. 41 | # Version 0.8 - 1st January 2016 - HTTPS SSL code implemented and working. Usually. There's all sorts of things out of my control that go wrong with this :( 42 | # Version 0.9 - 2nd January 2016 - Added menu option for SSL certificate update. Checks to see if server.xml is backed up before working on it. 43 | # - Tomcat set to use a max of 3Gb of server memory. 44 | # - cron job created to run an SSL cert refresh every month. 45 | # - This is due to LE's cert lifetime of 90 days and cron's inability to run past daily, monthly or yearly. 46 | # Version 1.0 - 4th January 2016 - RELEASE - LetsEncrypt is now an optional install. Log files repointed on JSS upgrades too. 47 | # - Cleaned up Tomcat caching issues with deleted instances. 48 | # Version 1.0 - 31st March 2016 - Redhat compatible version. No new features so not a version increment. 49 | # Version 1.1 - 12th April 2016 - Update of SSL cipher list to bring into line with https://jamfnation.jamfsoftware.com/article.html?id=384 50 | # Version 2.0 - 14th April 2016 - Merged both scripts together. Now one big universal version with better OS checking. 51 | # Version 2.1 - 16th April 2016 - Now manages Tomcat, MySQL and Java memory settings. Calculated per current formulas on JAMF's CJA course. 52 | # Version 2.2 - 18th April 2016 - Optional redirection of HTTPS traffic to port 443 from 8443 via firewall rules. 53 | # Version 2.3 - 21st April 2016 - Tomcat really doesn't like running with less than 1Gb ram, so we check for 1.5Gb available. Quit if not available. 54 | # Version 2.4 - 22nd April 2016 - Choice of which supported Java version to install. In variable below. 55 | # Version 2.5 - 15th June 2016 - Fixed missing rule in UFW configuration. Also fixed bug where connector keystore file isn't set properly. 56 | # Version 2.6 - 23rd June 2016 - Recoded large chunks of the LetsEncrypt code due to them suddenly getting distribution via repo AND changing the name of the binary that does the work. 57 | # Version 2.7 - 14th July 2016 - Added code to make sure that tomcat webapp folders have correct ownership of the appropriate tomcat user. 58 | # Version 3.0 - 4th August 2016 - Removed Java 7, upgraded Tomcat to version 8. Refactored all the relevant code and paths to compensate for manual install. Down 300+ lines for same functionality! 59 | # Version 3.1 - 6th August 2016 - Cleaned up some embarrassing typos and code swapping to do with LetsEncrypt. Also some interesting Tomcat 8 server.xml changes. 60 | # Big thanks to Cody Butcher for his help on this! 61 | # Version 3.2 - 17th February 2017 - Fixed some pesky mysql error redirection stuff. Won't be prompted for insecure command line anymore! 62 | # Fixed some very annoying tomcat webapp folder ownership stuff that never worked properly. Apparently. 63 | # Version 3.3 - 23rd February 2017 - Brought the Tomcat HTTPS connector settings into line with Jamf's current documentation. 64 | # Version 3.5 - 23rd February 2017 - Major update to use Ubuntu 16.04 LTS in place of 14.04 LTS. Java now uses OpenJDK 8 on both OS. Tomcat has a unified systemd launcher. Code simplified. 65 | # Big thanks to Rich Trouton for quickly helping me with the systemd testing today! 66 | # Version 4.0 - 21st March 2017 - Change MySQL to install 5.7.14 or better with the release of JSS 9.98. Please note new password complexity requirements for db's! 67 | # - Also fixed DUMB deltarpm bug. Removed MaxPermGen setting for Tomcat as Java 8 doesn't support it. Replaced with MetaspaceSize stuff. 68 | # - Replaced LetsEncrypt crontab with a systemd job. OpenJDK replaced with Oracle for BOTH OS platforms due to CPU hammering issues. 69 | # Version 4.1 - 27th March 2017 - Whoops, forgot to clean up a file. Thrown in some extra commands for db integrity checking post upload of database dump file. 70 | # - DB check code thanks to Neil Martin: https://soundmacguy.wordpress.com/2017/03/27/jamf-pro-9-98-on-windows-migrating-to-mysql-5-7/ 71 | # Version 4.2 - 9th May 2017 - Fixed LetsEncrypt bug caused by deleting the wrong line in Tomcat server.xml file 72 | # Version 4.3 - 17th May 2017 - Fixed code for new instance creation. Some of the variables were pointing to non-existant file paths. I do wonder what I was thinking at the time. Let's see if people read this. 73 | # Version 4.4 - 19th May 2017 - Sole change to disable password complexity rules on MySQL 5.7 74 | # Version 4.5 - 22nd June 2017 - Fixed bug with HTTPS config for tomcat. Was missing a closing bracket! 75 | # Version 4.6 - 3rd August 2017 - Updated tomcat config due to new jamf security paper: https://resources.jamf.com/documents/white-papers/Securing-Your-Jamf-Server.pdf 76 | # - Corrected very old systemd config bug with LetsEncrypt cert renewal timers. 77 | # Version 4.7 - 7th August 2017 - It was pointed out to me that if Tomcat crashes, it would not auto restart. Fixed SystemD config to compensate. Also fixed shutdown and some RedHat java bugs. 78 | # Version 4.8 - 16th August 2017 - Seems deleting instances wasn't cleaning out the Tomcat work folders properly. Fixed. 79 | 80 | # Set up variables to be used here 81 | 82 | # These variables are user modifiable. Don't forget to configure firewall settings from Line 737! 83 | 84 | export useract="richardpurves" # Server admin username. Used for home location. 85 | 86 | export letsencrypt="FALSE" # Set this to TRUE if you are going to use LetsEncrypt as your HTTPS Certificate Authority. 87 | export sslTESTMODE="TRUE" # Set this to FALSE when you're confident it's generating proper certs for you 88 | export httpsredirect="FALSE" # Set this to TRUE if you want your JSS to appear to be on port 443 using HTTPS 89 | export ssldomain="jssinabox.domain.com" # Domain name for the SSL certificates 90 | export sslemail="richard at richard-purves.com" # E-mail address for the SSL CA 91 | export sslkeypass="changeit" # Password to the keystore. Default is "changeit". Please change it! 92 | 93 | export mysqluser="root" # MySQL root account 94 | export mysqlpw="Changeit1!" # MySQL root account password. Please change it and note security requirements below: 95 | # At least one upper case letter, one lower case letter, 96 | # one digit, and one special character 97 | # and a minimum length of at least 8 characters. 98 | export mysqlserveraddress="localhost" # IP/Hostname of MySQL server. Default is local server. 99 | 100 | export dbuser="jamfsoftware" # Database username for JSS 101 | export dbpass="Changeit1!" # Database password for JSS. Default is "changeit". Please change it and see MySQL restrictions above. 102 | 103 | # These variables should not be tampered with or script functionality will be affected! 104 | 105 | currentdir=$( pwd ) 106 | currentver="4.8" 107 | currentverdate="16th August 2017" 108 | 109 | export homefolder="/home/$useract" # Home folder base path 110 | export rootwarloc="$homefolder" # Location of where you put the ROOT.war file 111 | export logfiles="/var/log/JSS" # Location of ROOT and instance JSS log files 112 | 113 | export tomcatloc="/opt/tomcat8" # Tomcat's installation path 114 | export webapploc="$tomcatloc/webapps" # Tomcat web application install path 115 | export cacheloc="$tomcatloc/work/Catalina/localhost" # Tomcat's webapp cache folder 116 | export user="tomcat" # User and Group used for tomcat 117 | export sslkeystorepath="$tomcatloc/keystore" # Keystore path 118 | export server="$tomcatloc/conf/server.xml" # Tomcat server.xml path 119 | 120 | export ubmycnfloc="/etc/mysql/my.cnf" # MySQL's configuration file path(s) 121 | export rhmycnfloc="/etc/my.cnf" 122 | 123 | export DataBaseLoc="WEB-INF/xml" # DataBase.xml location inside the JSS webapp 124 | export DataBaseXML="$rootwarloc/DataBase.xml.original" # Location of the tmp DataBase.xml file we use for reference 125 | 126 | export lepath="/etc/letsencrypt/live" # LetsEncrypt's certificate storage location 127 | 128 | # All functions to be set up here 129 | 130 | WhichDistAmI() 131 | { 132 | # First check is for Ubuntu 14.04 LTS 133 | if [ -f "/usr/bin/lsb_release" ]; 134 | then 135 | ubuntuVersion=`lsb_release -s -d` 136 | 137 | case $ubuntuVersion in 138 | *"Ubuntu 16.04"*) 139 | OS="Ubuntu" 140 | export OS 141 | ;; 142 | 143 | *) 144 | echo -e "Script requires Ubuntu 16.04 LTS. Exiting." 145 | exit 1 146 | ;; 147 | esac 148 | fi 149 | 150 | # Second check is for RedHat 7.x 151 | if [ -f "/etc/redhat-release" ]; 152 | then 153 | version=$( cat /etc/redhat-release | awk '{ print $7 }' | cut -c 1 ) 154 | 155 | # Is this RedHat 7 server? 156 | if [[ $version != "7" ]]; 157 | then 158 | echo -e "Script requires RedHat 7.x. Exiting." 159 | exit 1 160 | else 161 | echo -e "Redhat 7 detected. Proceeding." 162 | OS="RedHat" 163 | export OS 164 | fi 165 | fi 166 | 167 | # Last check is to see if we got a bite or not 168 | if [[ $OS != "Ubuntu" && $OS != "RedHat" ]]; 169 | then 170 | echo -e "Script requires either Ubuntu 16.04 LTS or RHEL 7.x. Exiting." 171 | exit 1 172 | fi 173 | } 174 | 175 | AmIroot() 176 | { 177 | # Check for root, quit if not present with a warning. 178 | if [[ "$(id -u)" != "0" ]]; 179 | then 180 | echo -e "Script needs to be run as root." 181 | exit 1 182 | else 183 | echo -e "Script running as root. Proceeding." 184 | fi 185 | } 186 | 187 | IsROOTwarPresent() 188 | { 189 | # Check for presence of ROOT.war file or we can't upgrade at all! 190 | if [ ! -f "$rootwarloc/ROOT.war" ]; 191 | then 192 | echo -e "\nMissing ROOT.war file from path: $rootwarloc \nPlease copy file to location and try again." 193 | exit 1 194 | else 195 | echo -e "\nROOT.war present at path: $rootwarloc. Proceeding." 196 | fi 197 | } 198 | 199 | TomcatService() 200 | { 201 | systemctl $1 tomcat 202 | } 203 | 204 | MySQLService() 205 | { 206 | if [[ $OS = "Ubuntu" ]]; 207 | then 208 | systemctl $1 mysql 209 | fi 210 | 211 | if [[ $OS = "RedHat" ]]; 212 | then 213 | systemctl $1 mysqld 214 | fi 215 | } 216 | 217 | CheckMySQL() 218 | { 219 | if [[ $OS = "Ubuntu" ]]; 220 | then 221 | export mysql=$(dpkg -l | grep "mysql-server" >/dev/null && echo "yes" || echo "no") 222 | fi 223 | 224 | if [[ $OS = "RedHat" ]]; 225 | then 226 | export mysql=$(yum -q list installed mysql-community-server &>/dev/null && echo "yes" || echo "no") 227 | fi 228 | } 229 | 230 | InstanceList() 231 | { 232 | # Is Tomcat present? 233 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 234 | 235 | if [[ $tomcat = "no" ]]; 236 | then 237 | echo -e "\nTomcat 8 not present. Please install before trying again." 238 | else 239 | echo -e "\nJSS Instance List\n-----------------\n" 240 | find $tomcatloc/webapps/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///' 241 | fi 242 | } 243 | 244 | SetupTomcatUser() 245 | { 246 | export user="tomcat" 247 | } 248 | 249 | SetupLogs() 250 | { 251 | # Check and create the JSS log file folder if missing with appropriate permissions. 252 | if [ ! -d $logfiles ]; 253 | then 254 | mkdir $logfiles 255 | SetupTomcatUser 256 | chown -R $user:$user $logfiles 257 | fi 258 | } 259 | 260 | UpdatePkgMgr() 261 | { 262 | if [[ $OS = "Ubuntu" ]]; 263 | then 264 | echo -e "\nUpdating apt-get repository ...\n" 265 | apt-get update -q 266 | 267 | echo -e "\nUpgrading installed packages ...\n" 268 | apt-get upgrade -q -y 269 | fi 270 | 271 | if [[ $OS = "RedHat" ]]; 272 | then 273 | 274 | # Is the delta RPM module installed? 275 | deltarpm=$(yum -q list installed deltarpm &>/dev/null && echo "yes" || echo "no") 276 | 277 | if [[ $deltarpm = "no" ]]; 278 | then 279 | echo -e "\nInstalling Delta RPM functionality\n" 280 | yum -q -y install deltarpm 281 | else 282 | echo -e "\nDelta RPM already present. Proceeding." 283 | fi 284 | 285 | echo -e "\nUpdating yum repository ...\n" 286 | yum -q -y update 287 | fi 288 | } 289 | 290 | InstallGit() 291 | { 292 | if [[ $OS = "Ubuntu" ]]; 293 | then 294 | # Is git present? 295 | git=$(dpkg -l | grep -w "git" >/dev/null && echo "yes" || echo "no") 296 | 297 | if [[ $git = "no" ]]; 298 | then 299 | echo -e "\ngit not present. Installing\n" 300 | apt-get install -q -y git 301 | else 302 | echo -e "\ngit already present. Proceeding." 303 | fi 304 | fi 305 | 306 | if [[ $OS = "RedHat" ]]; 307 | then 308 | # Is git present? 309 | git=$(yum -q list installed git &>/dev/null && echo "yes" || echo "no" ) 310 | 311 | if [[ $git = "no" ]]; 312 | then 313 | echo -e "\ngit not present. Installing." 314 | yum -q -y install git 315 | else 316 | echo -e "\ngit already present. Proceeding." 317 | fi 318 | fi 319 | } 320 | 321 | InstallCurl() 322 | { 323 | if [[ $OS = "Ubuntu" ]]; 324 | then 325 | # Is curl present? 326 | git=$(dpkg -l | grep -w "curl" >/dev/null && echo "yes" || echo "no") 327 | 328 | if [[ $git = "no" ]]; 329 | then 330 | echo -e "\ncurl not present. Installing\n" 331 | apt-get install -q -y curl 332 | else 333 | echo -e "\ncurl already present. Proceeding." 334 | fi 335 | fi 336 | 337 | if [[ $OS = "RedHat" ]]; 338 | then 339 | # Is wget present? 340 | wget=$(yum -q list installed curl &>/dev/null && echo "yes" || echo "no" ) 341 | 342 | if [[ $wget = "no" ]]; 343 | then 344 | echo -e "\nwcurl not present. Installing." 345 | yum -q -y install curl 346 | else 347 | echo -e "\ncurl already present. Proceeding." 348 | fi 349 | fi 350 | } 351 | 352 | InstallWget() 353 | { 354 | if [[ $OS = "Ubuntu" ]]; 355 | then 356 | # Is wget present? 357 | git=$(dpkg -l | grep -w "wget" >/dev/null && echo "yes" || echo "no") 358 | 359 | if [[ $git = "no" ]]; 360 | then 361 | echo -e "\nwget not present. Installing\n" 362 | apt-get install -q -y wget 363 | else 364 | echo -e "\nwget already present. Proceeding." 365 | fi 366 | fi 367 | 368 | if [[ $OS = "RedHat" ]]; 369 | then 370 | # Is wget present? 371 | wget=$(yum -q list installed wget &>/dev/null && echo "yes" || echo "no" ) 372 | 373 | if [[ $wget = "no" ]]; 374 | then 375 | echo -e "\nwget not present. Installing." 376 | yum -q -y install wget 377 | else 378 | echo -e "\nwget already present. Proceeding." 379 | fi 380 | fi 381 | } 382 | 383 | InstallUnzip() 384 | { 385 | if [[ $OS = "Ubuntu" ]]; 386 | then 387 | # Is unzip installed? 388 | unzip=$(dpkg -l | grep -w "unzip" >/dev/null && echo "yes" || echo "no") 389 | 390 | if [[ $unzip = "no" ]]; 391 | then 392 | echo -e "\nunzip not present. Installing\n" 393 | apt-get install -q -y unzip 394 | else 395 | echo -e "\nunzip already present. Proceeding." 396 | fi 397 | fi 398 | 399 | if [[ $OS = "RedHat" ]]; 400 | then 401 | # Is unzip installed? 402 | unzip=$(yum -q list installed unzip &>/dev/null && echo "yes" || echo "no" ) 403 | 404 | if [[ $unzip = "no" ]]; 405 | then 406 | echo -e "\nunzip not present. Installing\n" 407 | yum -q -y install unzip 408 | else 409 | echo -e "\nunzip already present. Proceeding." 410 | fi 411 | fi 412 | } 413 | 414 | PrepDBfile() 415 | { 416 | # Is unzip installed? Check by calling the unzip function. 417 | InstallUnzip 418 | 419 | # Check for presence of DataBase.xml.original file. 420 | # If missing, extract the DataBase.xml and place it in the $rootwarloc directory 421 | # Rename to DataBase.xml.original 422 | if [ ! -f "$rootwarloc/DataBase.xml.original" ]; 423 | then 424 | echo -e "\nExtracting DataBase.xml from ROOT.war\n" 425 | unzip -j $rootwarloc/ROOT.war "WEB-INF/xml/DataBase.xml" -d $rootwarloc 426 | mv $rootwarloc/DataBase.xml $rootwarloc/DataBase.xml.original 427 | else 428 | echo -e "\nDataBase.xml.original found at path: $rootwarloc. Proceeding." 429 | fi 430 | } 431 | 432 | InstallFirewall() 433 | { 434 | if [[ $OS = "Ubuntu" ]]; 435 | then 436 | # Is UFW present? 437 | ufw=$(dpkg -l | grep "ufw" >/dev/null && echo "yes" || echo "no") 438 | 439 | if [[ $ufw = "no" ]]; 440 | then 441 | echo -e "\nufw not present. Installing.\n" 442 | apt-get install -q -y ufw 443 | else 444 | echo -e "\nufw already installed. Proceeding." 445 | fi 446 | fi 447 | 448 | if [[ $OS = "RedHat" ]]; 449 | then 450 | # Is firewalld installed? 451 | fwd=$(yum -q list installed firewalld &>/dev/null && echo "yes" || echo "no" ) 452 | 453 | if [[ $fwd = "no" ]]; 454 | then 455 | echo -e "\nFirewallD not present. Installing." 456 | yum -q -y install firewalld 457 | else 458 | echo -e "\nFirewallD already installed. Proceeding." 459 | fi 460 | fi 461 | } 462 | 463 | InstallOpenSSH() 464 | { 465 | if [[ $OS = "Ubuntu" ]]; 466 | then 467 | # Is OpenSSH present? 468 | openssh=$(dpkg -l | grep "openssh" >/dev/null && echo "yes" || echo "no") 469 | 470 | if [[ $openssh = "no" ]]; 471 | then 472 | echo -e "\nopenssh not present. Installing.\n" 473 | apt-get install -q -y openssh 474 | else 475 | echo -e "\nopenssh already installed. Proceeding." 476 | fi 477 | fi 478 | 479 | if [[ $OS = "RedHat" ]]; 480 | then 481 | # Is OpenSSH present? 482 | openssh=$(yum -q list installed openssh &>/dev/null && echo "yes" || echo "no" ) 483 | 484 | if [[ $openssh = "no" ]]; 485 | then 486 | echo -e "\nopenssh not present. Installing.\n" 487 | yum -q -y install openssh 488 | else 489 | echo -e "\nopenssh already installed. Proceeding." 490 | fi 491 | fi 492 | } 493 | 494 | InstallOpenVMTools() 495 | { 496 | if [[ $OS = "Ubuntu" ]]; 497 | then 498 | # Are the open-vm-tools present? 499 | openvmtools=$(dpkg -l | grep "open-vm-tools" >/dev/null && echo "yes" || echo "no") 500 | 501 | if [[ $openvmtools = "no" ]]; 502 | then 503 | echo -e "\nopen vm tools not present. Installing." 504 | 505 | echo -e "\nGetting VMware packaging keys from server." 506 | wget http://packages.vmware.com/tools/keys/VMWARE-PACKAGING-GPG-DSA-KEY.pub 507 | wget http://packages.vmware.com/tools/keys/VMWARE-PACKAGING-GPG-RSA-KEY.pub 508 | 509 | echo -e "\nInstalling VMware packaging keys into apt." 510 | apt-key add ./VMWARE-PACKAGING-GPG-DSA-KEY.pub 511 | apt-key add ./VMWARE-PACKAGING-GPG-RSA-KEY.pub 512 | 513 | echo -e "\nCleaning up key files." 514 | rm ./VMWARE-PACKAGING-GPG-DSA-KEY.pub 515 | rm ./VMWARE-PACKAGING-GPG-RSA-KEY.pub 516 | 517 | echo -e "\nInstalling open vm tools." 518 | apt-get install -q -y open-vm-tools 519 | else 520 | echo -e "\nopen vm tools already installed. Proceeding." 521 | fi 522 | fi 523 | 524 | if [[ $OS = "RedHat" ]]; 525 | then 526 | # Are the open-vm-tools present? 527 | openvmtools=$(yum -q list installed open-vm-tools &>/dev/null && echo "yes" || echo "no" ) 528 | 529 | if [[ $openvmtools = "no" ]]; 530 | then 531 | echo -e "\nopen vm tools not present. Installing." 532 | yum -q -y install open-vm-tools 533 | else 534 | echo -e "\nopen vm tools already installed. Proceeding." 535 | fi 536 | fi 537 | } 538 | 539 | InstallJava() 540 | { 541 | if [[ $OS = "Ubuntu" ]]; 542 | then 543 | # Is Oracle Java 1.8 present? 544 | java8=$(dpkg -l | grep "oracle-java8-installer" >/dev/null && echo "yes" || echo "no") 545 | 546 | if [[ $java8 = "no" ]]; 547 | then 548 | echo -e "\nOracle Java 8 not present. Installing." 549 | apt install -q -y software-properties-common 550 | 551 | echo -e "\nAdding webupd8team repository to list.\n" 552 | add-apt-repository -y ppa:webupd8team/java 553 | apt-get update -q 554 | 555 | echo -e "\nInstalling Oracle Java 8.\n" 556 | echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections 557 | apt-get install -q -y oracle-java8-installer 558 | 559 | echo -e "\nSetting Oracle Java 8 to the system default.\n" 560 | apt-get install -q -y oracle-java8-set-default 561 | 562 | echo -e "\nSetting JAVA_HOME to use Oracle Java 8.\n" 563 | echo "JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java " >> /etc/environment 564 | 565 | echo -e "\nInstalling Java Cryptography Extension 8\n" 566 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip > $rootwarloc/jce_policy-8.zip 567 | unzip $rootwarloc/jce_policy-8.zip 568 | cp $rootwarloc/UnlimitedJCEPolicyJDK8/* /usr/lib/jvm/java-8-oracle/jre/lib/security 569 | rm $rootwarloc/jce_policy-8.zip 570 | rm -rf $rootwarloc/UnlimitedJCEPolicyJDK8 571 | else 572 | echo -e "\nOracle Java 8 already installed. Proceeding." 573 | fi 574 | fi 575 | 576 | if [[ $OS = "RedHat" ]]; 577 | then 578 | # Is Oracle Java 1.8 present? 579 | java8=$( [ -d "/usr/java" ] && echo "yes" || echo "no" ) 580 | 581 | if [[ $java8 = "no" ]]; 582 | then 583 | echo -e "\nOracle Java 8 not present. Installing." 584 | 585 | echo -e "\nFinding latest RPM download link.\n" 586 | dl=$( curl -s "https://www.java.com/en/download/manual.jsp" | grep "x64 RPM" | grep -Eo "(http)://[a-zA-Z0-9./?=_-]*" | awk "NR>1{print $1}" ) 587 | 588 | echo -e "\nDownloading latest Oracle Java RPM\n" 589 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" "$dl" > $rootwarloc/oracle-java.rpm 590 | 591 | echo -e "\nInstalling Oracle Java RPM\n" 592 | rpm -ivh $rootwarloc/oracle-java.rpm 593 | 594 | echo -e "\nCleaning up downloaded files\n" 595 | rm $rootwarloc/oracle-java.rpm 596 | 597 | echo -e "\nSetting JAVA_HOME to use Oracle Java 8.\n" 598 | echo "JAVA_HOME=/usr/java/default/" >> /etc/environment 599 | 600 | echo -e "\nInstalling Java Cryptography Extension 8\n" 601 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip > $rootwarloc/jce_policy-8.zip 602 | unzip $rootwarloc/jce_policy-8.zip 603 | cp $rootwarloc/UnlimitedJCEPolicyJDK8/* /usr/java/default/lib/security 604 | rm $rootwarloc/jce_policy-8.zip 605 | rm -rf $rootwarloc/UnlimitedJCEPolicyJDK8 606 | else 607 | echo -e "\nOracle 8 already installed. Proceeding." 608 | fi 609 | fi 610 | } 611 | 612 | InstallTomcat() 613 | { 614 | # Is Tomcat present? 615 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 616 | 617 | if [[ $tomcat = "no" ]]; 618 | then 619 | echo -e "\nTomcat 8 not installed. Installing." 620 | 621 | # Create tomcat group 622 | echo -e "\nCreating user group: $user" 623 | groupadd $user 624 | 625 | if [[ $OS = "Ubuntu" ]]; 626 | then 627 | echo -e "\nUbuntu detected." 628 | 629 | # Create tomcat user - Ubuntu 14.04 LTS 630 | echo -e "\nCreating tomcat user: $user" 631 | useradd -s /bin/false -g "$user" -d /opt/tomcat "$user" 632 | fi 633 | 634 | if [[ $OS = "RedHat" ]]; 635 | then 636 | echo -e "\nRedHat detected." 637 | 638 | # Create tomcat user - RHEL 7.x 639 | echo -e "\nCreating tomcat user: $user" 640 | useradd -M -s /sbin/nologin -g "$user" -d /opt/tomcat "$user" 641 | fi 642 | 643 | # Create systemd script so tomcat can run as a service 644 | echo -e "\nCreating systemd script for Tomcat 8" 645 | 646 | systemd='# Systemd unit file for tomcat 647 | # Created by JSS in a Box 648 | [Unit] 649 | Description=Apache Tomcat Web Application Container 650 | After=syslog.target network.target 651 | 652 | [Service] 653 | Type=forking 654 | 655 | ExecStart=/opt/tomcat8/bin/startup.sh 656 | ExecStop=/opt/tomcat8/bin/shutdown.sh 657 | 658 | User=tomcat 659 | Group=tomcat 660 | 661 | Restart=on-failure 662 | RestartSec=5 663 | 664 | [Install] 665 | WantedBy=multi-user.target 666 | Alias=tomcat.service' 667 | 668 | echo "$systemd" > /lib/systemd/system/tomcat.service 669 | systemctl daemon-reload 670 | 671 | # Find latest tomcat version 672 | echo -e "\nFinding latest Tomcat 8 version" 673 | version=$( curl -s http://tomcat.apache.org/download-80.cgi | grep "

]*>", "")}1' ) 674 | echo -e "\nVersion: $version" 675 | 676 | # Work out proper download path 677 | path="http://www.apache.org/dist/tomcat/tomcat-8/v${version}/bin/apache-tomcat-${version}.tar.gz" 678 | 679 | # Grab the latest .tar.gz distribution and install to /opt 680 | echo -e "\nDownloading and installing latest Tomcat 8" 681 | cd /opt 682 | wget $path 683 | tar -xzf /opt/apache-tomcat-${version}.tar.gz 684 | mv /opt/apache-tomcat-${version} "$tomcatloc" 685 | rm /opt/apache-tomcat-${version}.tar.gz 686 | 687 | # Configure permissions on tomcat installation 688 | echo -e "\nConfiguring Tomcat folder permissions" 689 | chown -R $user:$user $tomcatloc 690 | chmod g+rwx $tomcatloc/conf 691 | chmod g+r $tomcatloc/conf/* 692 | 693 | chmod g+rwx $tomcatloc/webapps 694 | chmod g+r $tomcatloc/webapps/* 695 | 696 | # Configure Tomcat environment variable 697 | echo -e "\nSetting Tomcat environment variable" 698 | echo "export CATALINA_HOME="${tomcatloc}"" >> ~/.bashrc 699 | source ~/.bashrc 700 | 701 | # Create Tomcat setenv.sh configuration file 702 | setenv='#!/bin/bash 703 | 704 | # Tomcat configuration file. Generated by JSS-in-a-Box. 705 | 706 | CATALINA_BASE='"'$tomcatloc'"' 707 | CATALINA_HOME="$CATALINA_BASE" 708 | CATALINA_OPTS="-Xms1024m -Xmx3072m" 709 | CATALINA_OPTS="$CATALINA_OPTS -Xss256k" 710 | CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=512m" 711 | CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=3072m" 712 | CATALINA_OPTS="$CATALINA_OPTS -XX:MaxGCPauseMillis=1500" 713 | CATALINA_OPTS="$CATALINA_OPTS -XX:GCTimeRatio=9" 714 | CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true" 715 | CATALINA_OPTS="$CATALINA_OPTS -server" 716 | CATALINA_OPTS="$CATALINA_OPTS -XX:+DisableExplicitGC" 717 | CATALINA_OPTS="$CATALINA_OPTS -Djava.security.egd=file:/dev/./urandom"' 718 | 719 | echo "$setenv" > $tomcatloc/bin/setenv.sh 720 | chown tomcat:tomcat $tomcatloc/bin/setenv.sh 721 | chmod 750 $tomcatloc/bin/setenv.sh 722 | 723 | # Clean default tomcat webapps out. We don't require them and could be a security hazard. 724 | echo -e "\nClearing out Tomcat default installations" 725 | rm -rf $tomcatloc/webapps/* 2>/dev/null 726 | 727 | echo -e "\nEnabling Tomcat to start on system restart" 728 | systemctl enable tomcat 729 | else 730 | echo -e "\nTomcat already present. Proceeding." 731 | fi 732 | } 733 | 734 | InstallMySQL() 735 | { 736 | if [[ $OS = "Ubuntu" ]]; 737 | then 738 | # Is MySQL 5.7 present? 739 | mysql=$(dpkg -l | grep "mysql-server-5.7" >/dev/null && echo "yes" || echo "no") 740 | 741 | if [[ $mysql = "no" ]]; 742 | then 743 | echo -e "\nMySQL 5.7 not present. Installing\n" 744 | 745 | echo -e "\nPreconfiguration of MySQL repo before adding to system\n" 746 | export DEBIAN_FRONTEND=noninteractive 747 | debconf-set-selections <<< "mysql-server-5.7 mysql-server/root_password password $mysqlpw" 748 | debconf-set-selections <<< "mysql-server-5.7 mysql-server/root_password_again password $mysqlpw" 749 | 750 | echo -e "\nAdding MySQL APT repo to system\n" 751 | wget https://dev.mysql.com/get/mysql-apt-config_0.8.3-1_all.deb -P $homefolder 752 | dpkg -i $homefolder/mysql-apt-config_0.8.3-1_all.deb 753 | apt-get update -q 754 | rm $homefolder/mysql-apt-config_0.8.3-1_all.deb 755 | 756 | echo -e "\nInstalling MySQL 5.7\n" 757 | apt-get install -q -y mysql-server 758 | 759 | echo -e "\nEnabling MySQL to start on system restart" 760 | systemctl enable mysql 761 | 762 | echo -e "\nStarting MySQL 5.7" 763 | MySQLService start 764 | else 765 | echo -e "\nMySQL 5.7 already present. Proceeding." 766 | fi 767 | fi 768 | 769 | if [[ $OS = "RedHat" ]]; 770 | then 771 | # Is MySQL 5.7 present? 772 | mysql=$(yum -q list installed mysql-community-server &>/dev/null && echo "yes" || echo "no") 773 | 774 | if [[ $mysql = "no" ]]; 775 | then 776 | echo -e "\nMySQL 5.7 not present. Installing." 777 | 778 | echo -e "\nAdding MySQL 5.7 to yum repo list\n" 779 | wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm -P $homefolder 780 | rpm -ivh $homefolder/mysql57-community-release-el7-9.noarch.rpm 781 | rm $homefolder/mysql57-community-release-el7-9.noarch.rpm 782 | 783 | echo -e "\nInstalling MySQL 5.7\n" 784 | yum -y --nogpgcheck install mysql-community-server 785 | 786 | echo -e "\nEnabling MySQL to start on system restart" 787 | systemctl enable mysqld 788 | 789 | echo -e "\nStarting MySQL 5.7" 790 | MySQLService start 791 | 792 | echo -e "\nChanging MySQL 5.7 root account password\n" 793 | temppw=$( grep 'temporary password' /var/log/mysqld.log | awk '{ print $11 }' ) 794 | mysql -h$mysqlserveraddress -u$mysqluser -p$temppw --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$mysqlpw';" 2>/dev/null 795 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "uninstall plugin validate_password;" 2>/dev/null 796 | else 797 | echo -e "\nMySQL 5.7 already present. Proceeding." 798 | fi 799 | fi 800 | } 801 | 802 | SetupFirewall() 803 | { 804 | # It's time to harden the server firewall. 805 | if [[ $OS = "Ubuntu" ]]; 806 | then 807 | # For Ubuntu, we're using UFW to do this. 808 | ufw --force disable # Disables the firewall before we make our changes 809 | ufw --force reset # Resets any firewall rules 810 | ufw allow ssh # Port 22 811 | # ufw allow http # Port 80 (JSS used to use this for xml lookups. Unsure if still needed.) 812 | ufw allow smtp # Port 25 813 | ufw allow ntp # Port 123 814 | # ufw allow ldap # Port 389 (unsecure port. use for internal servers only) 815 | # ufw allow ldaps # Port 636 (ssl ldap. hopefully to be used in preference to above) 816 | ufw allow https # Port 443 817 | ufw allow mysql # Port 3306 818 | ufw allow http-alt # Port 8080 (delete once you got SSL working) 819 | ufw allow 8443 # Port 8443 (delete if you enable 443 redirection or are using 8080 above) 820 | ufw allow 2195 # Apple Push Notification Service 821 | ufw allow 2196 # Apple Push Notification Service 822 | ufw allow 5223 # Apple Push Notification Service 823 | ufw allow 5228 # Google Cloud Messaging 824 | ufw --force enable # Turns on the firewall. May cause ssh disruption in the process. 825 | 826 | # Is https redirect enabled? If so, we have to set up some firewall rules to direct 8443 to 443. 827 | # We're going to use firewall port redirection as the alternative using authbind has proven unreliable. 828 | # And we have to add the rules manually before totally restarting the service too. Fun. 829 | if [[ $httpsredirect = "TRUE" ]]; 830 | then 831 | # Append the following lines into the before firewall rules file. 832 | echo "# Port 443 to 8443 redirect rules - added by JSS in a Box" >> /etc/ufw/before.rules 833 | echo "*nat" >> /etc/ufw/before.rules 834 | echo ":PREROUTING ACCEPT [0:0]" >> /etc/ufw/before.rules 835 | echo "-A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443" >> /etc/ufw/before.rules 836 | echo "COMMIT" >> /etc/ufw/before.rules 837 | 838 | # Restart the entire UFW service or this won't work until reboot. 839 | service ufw restart 840 | fi 841 | fi 842 | 843 | if [[ $OS = "RedHat" ]]; 844 | then 845 | # For RedHat, we're using FireWallD. 846 | echo -e "\nEnabling FirewallD service." 847 | systemctl start firewalld 848 | 849 | echo -e "\nConfiguring FirewallD service\n" 850 | firewall-cmd --permanent --add-service=ssh 851 | firewall-cmd --permanent --add-service=http 852 | firewall-cmd --permanent --add-service=smtp 853 | firewall-cmd --permanent --add-service=ntp 854 | #firewall-cmd --permanent --add-service=ldap 855 | #firewall-cmd --permanent --add-service=ldaps 856 | firewall-cmd --permanent --add-service=https 857 | firewall-cmd --permanent --add-service=mysql 858 | firewall-cmd --permanent --add-port=8080/tcp # HTTP JSS (delete once you got SSL working) 859 | firewall-cmd --permanent --add-port=8443/tcp # HTTPS JSS (delete 8080 once you got SSL working) 860 | firewall-cmd --permanent --add-port=2195/tcp # Apple Push Notification Service 861 | firewall-cmd --permanent --add-port=2196/tcp # Apple Push Notification Service 862 | firewall-cmd --permanent --add-port=5223/tcp # Apple Push Notification Service 863 | firewall-cmd --permanent --add-port=5228/tcp # Google Cloud Messaging 864 | 865 | echo -e "\nEnabling FirewallD rule changes\n" 866 | firewall-cmd --reload 867 | 868 | echo -e "\nEnabling FirewallD to start on system reboot" 869 | systemctl enable firewalld 870 | 871 | # Is https redirect enabled? If so, we have to set up some firewall rules to direct 443 to 8443. 872 | # A little nicer than UFW, as there are commands to do this instead of directly manipulating firewall rules. 873 | if [[ $httpsredirect = "TRUE" ]]; 874 | then 875 | firewall-cmd --permanent --add-masquerade 876 | firewall-cmd --permanent --add-forward-port=port=443:proto=tcp:toport=8443 877 | firewall-cmd --reload 878 | fi 879 | fi 880 | } 881 | 882 | InstallLetsEncrypt() 883 | { 884 | # Is LetsEncrypt present? 885 | # This one is a git clone, rather than an installation for cross distro reasons. We'll be putting this in /opt/letsencrypt 886 | if [ ! -d "/opt/letsencrypt" ]; 887 | then 888 | echo -e "\nLetsEncrypt not present. Downloading installation script from dl.eff.org.\n" 889 | mkdir /opt/letsencrypt 890 | cd /opt/letsencrypt 891 | wget https://dl.eff.org/certbot-auto 892 | chmod +x /opt/letsencrypt/certbot-auto 893 | sudo -H /opt/letsencrypt/certbot-auto -n 894 | cd $currentdir 895 | else 896 | echo -e "\nLetsEncrypt is already installed. Proceeding." 897 | return 898 | fi 899 | 900 | # We'll be doing some work with Tomcat so let's stop the service to make sure we don't hurt anything. 901 | echo "\nStopping Tomcat service\n" 902 | TomcatService stop 903 | 904 | # Get LetsEncrypt to generate the appropriate certificate files for later processing. 905 | # We're using sudo -H even as root because there's some weird errors that happen if you don't. 906 | echo -e "\nObtaining Certificate from LetsEncrypt Certificate Authority\n" 907 | if [[ $sslTESTMODE = "TRUE" ]]; 908 | then 909 | sudo -H /opt/letsencrypt/certbot-auto certonly --standalone -m $sslemail -d $ssldomain --agree-tos --test-cert 910 | else 911 | sudo -H /opt/letsencrypt/certbot-auto certonly --standalone -m $sslemail -d $ssldomain --agree-tos 912 | fi 913 | 914 | # Code to generate a Java KeyStore for Tomcat from what's provided by LetsEncrypt 915 | # Based on work by Carmelo Scollo (https://melo.myds.me) 916 | # https://community.letsencrypt.org/t/how-to-use-the-certificate-for-tomcat/3677/9 917 | 918 | # Create a keystore folder for Tomcat with the correct permissions 919 | mkdir $sslkeystorepath 920 | chown $user:$user $sslkeystorepath 921 | chmod 755 $sslkeystorepath 922 | 923 | # Ok we got LetsEncrypt certificate files, let's make a PKCS12 combined key file from them. 924 | echo -e "\nMerging LetsEncrypt certificates into a PKCS12 file\n" 925 | openssl pkcs12 \ 926 | -export \ 927 | -in $lepath/$ssldomain/fullchain.pem \ 928 | -inkey $lepath/$ssldomain/privkey.pem \ 929 | -out $sslkeystorepath/fullchain_and_key.p12 \ 930 | -password pass:$sslkeypass \ 931 | -name tomcat 932 | 933 | # Now we convert our .p12 file into a java keystore that Tomcat likes better. 934 | echo -e "\nConverting PKCS12 file into a Java KeyStore\n" 935 | keytool -importkeystore \ 936 | -deststorepass $sslkeypass \ 937 | -destkeypass $sslkeypass \ 938 | -destkeystore $sslkeystorepath/keystore.jks \ 939 | -srckeystore $sslkeystorepath/fullchain_and_key.p12 \ 940 | -srcstoretype PKCS12 \ 941 | -srcstorepass $sslkeypass \ 942 | -alias tomcat 943 | 944 | # Clean up on aisle three! 945 | rm $sslkeystorepath/fullchain_and_key.p12 946 | 947 | # Tomcat server.xml was previous prepared in the ConfigureMemoryUseage function. 948 | # Now we disable HTTP and enable the HTTPS connectors 949 | 950 | echo -e "\nDisabling Tomcat HTTP connector\n" 951 | sed -i '75i' $server 953 | 954 | echo -e "\nEnabling Tomcat HTTPS Connector with executor\n" 955 | sed -i '107d' $server 956 | sed -i '86d' $server 957 | 958 | # We're done here. Start 'er up. 959 | TomcatService start 960 | 961 | # Oh wait, we have to set up a periodic renewal since LetsEncrypt doesn't do that for Tomcat 962 | # (at time of coding - 23rd June 2016) 963 | # This should run every night at midnight. LE certs last 90 days but quicker is fine as it won't renew. 964 | # crontab -l | { echo "0 0 * * * $homefolder/jss-in-a-box.sh -s"; } | crontab - 965 | 966 | # We must set up a recurring job to renew the certs using systemd. 967 | # Using https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/ as a handy resource 968 | 969 | lerenew='[Unit] 970 | Description=LetsEncrypt Tomcat certificate renewal 971 | 972 | [Timer] 973 | OnCalendar=daily 974 | 975 | [Install] 976 | WantedBy=timers.target' 977 | 978 | echo "$lerenew" > /etc/systemd/system/le-renew.timer 979 | 980 | leservice='[Unit] 981 | Description=LetsEncrypt Tomcat certificate renewal 982 | 983 | [Service] 984 | Type=simple 985 | Nice=19 986 | IOSchedulingClass=2 987 | IOSchedulingPriority=7 988 | ExecStart="$homefolder"/jss-in-a-box.sh -s' 989 | 990 | echo "$leservice" > /etc/systemd/system/le-renew.service 991 | 992 | # Files are in place. Start the timer and enable it for system reboots too. 993 | systemctl start le-renew.timer 994 | systemctl enable le-renew.timer 995 | } 996 | 997 | UpdateLeSSLKeys() 998 | { 999 | # update SSL keys from LetsEncrypt 1000 | 1001 | # Is LetsEncrypt present? 1002 | if [[ $letsencrypt = "FALSE" ]]; 1003 | then 1004 | echo -e "\nLetsEncrypt option disabled in script. Cannot proceed.\n" 1005 | return 1 1006 | else 1007 | # Derive the correct file locations from the current tomcat install location 1008 | export sslkeystorepath="$tomcatloc/keystore" 1009 | export server="$tomcatloc/conf/server.xml" 1010 | 1011 | # We'll be doing some work with Tomcat so let's stop the service to make sure we don't hurt anything. 1012 | echo -e "\nStopping Tomcat service\n" 1013 | TomcatService stop 1014 | 1015 | # Get LetsEncrypt to generate the appropriate certificate files for later processing. 1016 | # We're using sudo -H even as root because there's some weird errors that happen if you don't. 1017 | echo -e "\nObtaining Certificate from LetsEncrypt Certificate Authority\n" 1018 | if [[ $sslTESTMODE = "TRUE" ]]; 1019 | then 1020 | sudo -H /opt/letsencrypt/certbot-auto renew --dry-run 1021 | else 1022 | sudo -H /opt/letsencrypt/certbot-auto renew --quiet --no-self-upgrade 1023 | fi 1024 | 1025 | # Clean up the old keystore and keys 1026 | rm $sslkeystorepath/keystore.jks 1027 | 1028 | # Ok we got LetsEncrypt certificate files, let's make a PKCS12 combined key file from them. 1029 | echo -e "\nMerging LetsEncrypt certificates into a PKCS12 file" 1030 | openssl pkcs12 \ 1031 | -export \ 1032 | -in $lepath/$ssldomain/fullchain.pem \ 1033 | -inkey $lepath/$ssldomain/privkey.pem \ 1034 | -out $sslkeystorepath/fullchain_and_key.p12 \ 1035 | -password pass:$sslkeypass \ 1036 | -name tomcat 1037 | 1038 | # Now we convert our .p12 file into a java keystore that Tomcat likes better. 1039 | echo -e "\nConverting PKCS12 file into a Java KeyStore" 1040 | keytool -importkeystore \ 1041 | -deststorepass $sslkeypass \ 1042 | -destkeypass $sslkeypass \ 1043 | -destkeystore $sslkeystorepath/keystore.jks \ 1044 | -srckeystore $sslkeystorepath/fullchain_and_key.p12 \ 1045 | -srcstoretype PKCS12 \ 1046 | -srcstorepass $sslkeypass \ 1047 | -alias tomcat 1048 | 1049 | # Clean up on aisle three! 1050 | rm $sslkeystorepath/fullchain_and_key.p12 1051 | 1052 | # We're done here. Start 'er up. 1053 | echo -e "\nRestarting Tomcat server" 1054 | TomcatService start 1055 | fi 1056 | } 1057 | 1058 | ConfigureMemoryUsage() 1059 | { 1060 | # Derive the correct file locations from the current OS 1061 | webapps="$tomcatloc/webapps" 1062 | server="$tomcatloc/conf/server.xml" 1063 | sslkeystorepath="$tomcatloc/keystore" 1064 | server="$tomcatloc/conf/server.xml" 1065 | tomcatconf="$tomcatloc/bin" 1066 | 1067 | # Now we work out the correct memory and connection settings 1068 | # What's the default MaxPoolSize? 1069 | MaxPoolSize=$( cat $DataBaseXML | grep MaxPoolSize | sed 's/[^0-9]*//g' ) 1070 | echo -e "\nMax Pool Size : $MaxPoolSize" 1071 | 1072 | # How many JSS instances do we currently have? We need at least one, so check for that too. 1073 | NoOfJSSinstances=$( find $webapps/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///' | wc -l ) 1074 | if [ $NoOfJSSinstances -lt 1 ]; 1075 | then 1076 | NoOfJSSinstances=1 1077 | fi 1078 | echo -e "\nNo of current JSS instances: $NoOfJSSinstances" 1079 | 1080 | # MaxThreads = ( MaxPoolSize x 2.5 ) x no of webapps 1081 | MaxThreads=$( awk "BEGIN {print ($MaxPoolSize*2.5)*$NoOfJSSinstances}" ) 1082 | echo -e "\nOptimal Max Threads calculated to be: $MaxThreads" 1083 | 1084 | # Derive the maximum number of SQL connections based on the above information 1085 | # Formula is: Maximum Pool Size x No of JSS instances plus one ;) 1086 | MySQLMaxConnections=$( awk "BEGIN {print ($MaxPoolSize*$NoOfJSSinstances)+1}" ) 1087 | 1088 | # Work out the amount of system memory, convert to Mb and then subtract 256Mb 1089 | # That'll be what we'll allocate to Java as a maximum memory size. OS needs room too! 1090 | mem=$( grep MemTotal /proc/meminfo | awk '{ print $2 }' ) 1091 | memtotal=$( expr $mem / 1024 ) 1092 | memtotal=$( expr $memtotal - 256 ) 1093 | 1094 | # Well unless we get less than 1024Mb quit as we're in trouble. 1095 | # JSS will not like running that low so you will HAVE to boost your RAM allocation. 1096 | # I've been informed by JAMF support that 8Gb is ideal but I've run it on 4Gb without issue. 1097 | if [ $memtotal -lt 1536 ]; 1098 | then 1099 | echo -e "\nERROR: Not enough memory to allocate to Tomcat" 1100 | echo -e "\nNeeded minimum memory: 2048" 1101 | echo -e "\nAvailable memory: $memtotal" 1102 | echo -e "\nPlease increase available RAM on this server." 1103 | fi 1104 | 1105 | echo -e "\nMaximum memory to allocate to Tomcat is: $memtotal Mb" 1106 | 1107 | # Ok has Tomcat previously had it's server.xml altered by this script? Check for the backup. 1108 | if [ ! -f "$server.backup" ]; 1109 | then 1110 | # Configure the Tomcat server.xml. None of this stuff is pretty and could be better. Improvements welcome. 1111 | # Let's start by backing up the server.xml file in case things go wrong. 1112 | 1113 | echo -e "\nBacking up $server file" 1114 | cp $server $server.backup 1115 | 1116 | # Delete HTTPS connector settings 1117 | sed -i '84,88d' $server 1118 | 1119 | # Replace HTTPS connector settings 1120 | sed -i '84i' $server 1142 | 1143 | echo -e "\nEnabling Tomcat shared executor" 1144 | sed -i '59d' $server 1145 | sed -i '56d' $server 1146 | 1147 | echo -e "\nDisabling Tomcat default HTTP Connector" 1148 | sed -i '67i' $server 1150 | 1151 | echo -e "\nEnabling Tomcat HTTP Connector with executor" 1152 | sed -i '78d' $server 1153 | sed -i '73d' $server 1154 | 1155 | echo -e "\nAdding Max Threads to HTTP connector" 1156 | sed -i 's/' $server 1161 | fi 1162 | 1163 | # Now for the settings we'll be periodically adjusting 1164 | echo -e "\nConfiguring the TomcatThreadPool executor with current maximum threads" 1165 | sed -i 's/maxThreads="150" /maxThreads="'"$MaxThreads"'" /' $server 1166 | 1167 | # Configure max ram available to Java from what we worked out earlier. 1168 | echo -e "\nConfiguring Java to use $memtotal as max memory." 1169 | sed -i 's/-Xmx.*/-Xmx'"$memtotal"'m"/' $tomcatloc/bin/setenv.sh 1170 | sed -i 's/-XX:MaxMetaspaceSize=.*/-XX:MaxMetaspaceSize='"$memtotal"'m"/' $tomcatloc/bin/setenv.sh 1171 | 1172 | if [[ $OS = "Ubuntu" ]]; 1173 | then 1174 | # MySQL 1175 | echo -e "\nConfiguring MySQL max connections to $MySQLMaxConnections" 1176 | sed -i 's/max_connections.*/max_connections = '$MySQLMaxConnections'/' $ubmycnfloc 1177 | fi 1178 | 1179 | if [[ $OS = "RedHat" ]]; 1180 | then 1181 | # MySQL 1182 | echo -e "\nConfiguring MySQL max connections to: $MySQLMaxConnections" 1183 | sed -i 's/max_connections.*/max_connections = '$MySQLMaxConnections'/' $rhmycnfloc 1184 | fi 1185 | 1186 | # Time to restart MySQL and Tomcat 1187 | TomcatService stop 1188 | MySQLService restart 1189 | TomcatService start 1190 | } 1191 | 1192 | InitialiseServer() 1193 | { 1194 | # This is to make sure the appropriate services and software are installed and configured. 1195 | InstallGit 1196 | InstallCurl 1197 | InstallWget 1198 | InstallUnzip 1199 | InstallFirewall 1200 | InstallOpenSSH 1201 | InstallOpenVMTools 1202 | InstallJava # This includes the Cryptography Extensions 1203 | InstallTomcat 1204 | InstallMySQL 1205 | ConfigureMemoryUsage 1206 | SetupLogs 1207 | 1208 | if [[ $letsencrypt = TRUE ]]; 1209 | then 1210 | InstallLetsEncrypt 1211 | fi 1212 | 1213 | SetupFirewall 1214 | } 1215 | 1216 | CreateNewInstance() 1217 | { 1218 | # Check for presence of Tomcat and MySQL before proceeding 1219 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 1220 | CheckMySQL 1221 | 1222 | if [[ $tomcat = "no" || $mysql = "no" ]]; 1223 | then 1224 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again.\n" 1225 | return 1 1226 | fi 1227 | 1228 | # Call function to show all directory names in the tomcat webapps folder 1229 | InstanceList 1230 | 1231 | # Prompt for new instance name 1232 | echo -e "\nPlease enter a new instance name. (Or ROOT for a non-context JSS / enter key to skip)\n" 1233 | read -p "Name : " instance 1234 | 1235 | # Check for the skip 1236 | if [[ $instance = "" ]]; 1237 | then 1238 | echo -e "\nSkipping instance creation.\n" 1239 | return 1240 | fi 1241 | 1242 | # Does this name already exist? If so, ask again. 1243 | webapps=($(find $webapploc/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///')) 1244 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false 1245 | 1246 | if [[ $found = true ]]; 1247 | then 1248 | echo -e "\nInstance name already exists.\n" 1249 | return 1 1250 | fi 1251 | 1252 | # Stop tomcat service 1253 | TomcatService stop 1254 | 1255 | # Prep variables for future use based on current OS 1256 | SetupTomcatUser 1257 | 1258 | # Create the new database 1259 | echo -e "\nCreating new database for instance: $instance " 1260 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "CREATE DATABASE $instance;" 2>/dev/null 1261 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $instance.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null 1262 | 1263 | # Create the new tomcat instance 1264 | echo -e "\nInstalling JSS application to new instance: $instance" 1265 | 1266 | # Check if installing ROOT, if so just copy the file to the webapps folder 1267 | # Otherwise make a copy of the ROOT.war, rename it to the instance name and 1268 | # then move that to the webapps folder. 1269 | if [[ $instance = "ROOT" ]]; 1270 | then 1271 | cp $rootwarloc/ROOT.war $webapploc && unzip -oq $webapploc/ROOT.war -d $webapploc/ROOT 1272 | else 1273 | cp $rootwarloc/ROOT.war $webapploc/$instance.war && unzip -oq $webapploc/$instance.war -d $webapploc/$instance 1274 | fi 1275 | 1276 | # Create a specific DataBase.xml file for this new instance 1277 | echo -e "\nPreparing DataBase.xml for new instance: $instance" 1278 | sed -i "s/\(\).*\(<\/ServerName.*\)/\1$mysqlserveraddress\2/" $DataBaseXML 1279 | sed -i "s/\(\).*\(<\/DataBaseName.*\)/\1$instance\2/" $DataBaseXML 1280 | sed -i "s/\(\).*\(<\/DataBaseUser.*\)/\1$dbuser\2/" $DataBaseXML 1281 | sed -i "s/\(\).*\(<\/DataBasePassword.*\)/\1$dbpass\2/" $DataBaseXML 1282 | 1283 | # Wait for allow Tomcat to expand the .war file we copied over. 1284 | echo -e "\nWaiting for .war file to be expanded" 1285 | while [ ! -d "$webapploc/$instance" ] 1286 | do 1287 | echo -e "Awaiting Tomcat to expand instance: $instance" 1288 | sleep 3 1289 | done 1290 | sleep 5 1291 | 1292 | # Copy the new file over the top of the existing file. 1293 | echo -e "\nCopying the replacement DataBase.xml file into new instance: $instance" 1294 | cp "$DataBaseXML" $webapploc/$instance/$DataBaseLoc/DataBase.xml 1295 | 1296 | # Create the instance name and empty log files with an exception for ROOT 1297 | echo -e "\nCreating log files for new instance: $instance" 1298 | if [[ $instance = "ROOT" ]]; 1299 | then 1300 | touch $logfiles/JAMFChangeManagement.log 1301 | touch $logfiles/JAMFSoftwareServer.log 1302 | touch $logfiles/JSSAccess.log 1303 | chown -R $user:$user $logfiles 1304 | else 1305 | mkdir $logfiles/$instance 1306 | touch $logfiles/$instance/JAMFChangeManagement.log 1307 | touch $logfiles/$instance/JAMFSoftwareServer.log 1308 | touch $logfiles/$instance/JSSAccess.log 1309 | chown -R $user:$user $logfiles/$instance 1310 | fi 1311 | 1312 | # Finally modify the log4j file inside the new instance to point to the right files/folders 1313 | echo -e "\nModifying new instance: $instance to point to new log files" 1314 | if [[ $instance = "ROOT" ]]; 1315 | then 1316 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1317 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1318 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1319 | else 1320 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/$instance/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1321 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/$instance/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1322 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/$instance/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1323 | fi 1324 | 1325 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen! 1326 | chown -R $user:$user $webapploc/ 1327 | 1328 | # Recalculate memory usage since we've made changes 1329 | ConfigureMemoryUsage 1330 | } 1331 | 1332 | DeleteInstance() 1333 | { 1334 | # Check for presence of Tomcat and MySQL before proceeding 1335 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 1336 | CheckMySQL 1337 | 1338 | if [[ $tomcat = "no" || $mysql = "no" ]]; 1339 | then 1340 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again." 1341 | return 1 1342 | fi 1343 | 1344 | # Call function to show all directory names in the tomcat webapps folder 1345 | InstanceList 1346 | 1347 | # Prompt for the instance name 1348 | echo -e "\n" 1349 | read -p "Please enter a JSS instance to delete (or enter to skip) : " instance 1350 | 1351 | # Does this name already exist? 1352 | webapps=($(find $tomcatloc/webapps/* -maxdepth 0 -type d | sed -r 's/^.+\///')) 1353 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false 1354 | 1355 | if [[ $found = false ]]; 1356 | then 1357 | echo -e "\nInstance name does not exist." 1358 | return 1 1359 | fi 1360 | 1361 | # It does exist. Are they sure? Very very very VERY sure? 1362 | echo -e "\nWARNING: This will restart the Tomcat service!\n" 1363 | read -p "Are you completely certain? There is NO RECOVERY from this! (Y/N) : " areyousure 1364 | 1365 | case "$areyousure" in 1366 | 1367 | Y|y) 1368 | 1369 | # Stop the tomcat service 1370 | echo -e "\nStopping Tomcat service.\n" 1371 | TomcatService stop 1372 | 1373 | # Delete the tomcat ROOT.war folder 1374 | echo -e "\nDeleting Tomcat instance: $instance" 1375 | rm $tomcatloc/webapps/$instance.war 2>/dev/null 1376 | rm -rf $tomcatloc/webapps/$instance 1377 | 1378 | # Delete the database 1379 | echo -e "\nDeleting database for instance: $instance" 1380 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "DROP DATABASE $instance;" 2>/dev/null 1381 | 1382 | # Delete the logfiles 1383 | echo -e "\nDeleting log files for instance: $instance" 1384 | if [[ $instance = "ROOT" ]]; 1385 | then 1386 | rm $logfiles/JAMFSoftwareServer.log 2>/dev/null 1387 | rm $logfiles/JAMFChangeManagement.log 2>/dev/null 1388 | rm $logfiles/JSSAccess.log 2>/dev/null 1389 | else 1390 | rm -rf $logfiles/$instance 2>/dev/null 1391 | fi 1392 | 1393 | # Delete the tomcat cache folder 1394 | echo -e "\nDeleting Tomcat cache folder for instance: $instance" 1395 | if [[ $instance = "ROOT" ]]; 1396 | then 1397 | rm -rf $cacheloc/_ 2>/dev/null 1398 | rm -rf $cacheloc/ROOT 2>/dev/null 1399 | else 1400 | rm -rf $cacheloc/$instance 2>/dev/null 1401 | fi 1402 | 1403 | # Recalculate memory usage since we've made changes 1404 | ConfigureMemoryUsage 1405 | ;; 1406 | 1407 | *) 1408 | echo -e "\nSkipping deletion of instance" 1409 | ;; 1410 | 1411 | esac 1412 | } 1413 | 1414 | DumpDatabase() 1415 | { 1416 | # Is MySQL 5.7 present? 1417 | CheckMySQL 1418 | 1419 | if [[ $mysql = "no" ]]; 1420 | then 1421 | echo -e "\nMySQL 5.7 not installed. Please install before trying again.\n" 1422 | return 1 1423 | fi 1424 | 1425 | # Shows all JSS databases in MySQL but removing the SQL server specific ones. 1426 | echo -e "\nJSS Database List\n-----------------\n" 1427 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema" 1428 | 1429 | # Choose either a single instance or all of them 1430 | echo -e "\n" 1431 | read -p "Please enter an instance name to dump (or ALL for entire database) : " instance 1432 | 1433 | # Has the entire database been selected? 1434 | if [[ $instance = "ALL" ]]; 1435 | then 1436 | echo -e "\nDumping all databases to files." 1437 | databases=$( mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema" ) 1438 | 1439 | # Stop the tomcat service 1440 | echo -e "\nStopping Tomcat service." 1441 | TomcatService stop 1442 | 1443 | for db in $databases; do 1444 | echo "Dumping database: $db" 1445 | mysqldump -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db 2>/dev/null | gzip > $rootwarloc/$db.sql.gz 1446 | done 1447 | 1448 | # Restart tomcat 1449 | echo -e "\nRestarting Tomcat service" 1450 | TomcatService restart 1451 | return 1452 | fi 1453 | 1454 | # Does this name already exist? 1455 | dbs=($(mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema")) 1456 | [[ " ${dbs[@]} " =~ " $instance " ]] && found=true || found=false 1457 | 1458 | if [[ $found = false ]]; 1459 | then 1460 | echo -e "\nInstance name does not exist." 1461 | return 1 1462 | fi 1463 | 1464 | # Dump selected database table 1465 | echo -e "\nDumping database $instance ..." 1466 | mysqldump -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $instance 2>/dev/null | gzip > $rootwarloc/$instance.sql.gz 1467 | } 1468 | 1469 | UploadDatabase() 1470 | { 1471 | # Is MySQL 5.7 present? 1472 | CheckMySQL 1473 | 1474 | if [[ $mysql = "no" ]]; 1475 | then 1476 | echo -e "\nMySQL 5.7 not installed. Please install before trying again.\n" 1477 | return 1 1478 | fi 1479 | 1480 | # Show list of backup files 1481 | echo -e "\nDatabase Backup List\n-----------------\n" 1482 | find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///' 1483 | 1484 | # Ask which file to restore 1485 | echo -e "\n" 1486 | read -p "Please enter filename to restore (enter to skip / ALL for everything!) : " dbname 1487 | 1488 | # Has the entire database been selected? 1489 | if [[ $dbname = "ALL" ]]; 1490 | then 1491 | echo -e "\nWARNING: This will overwrite ALL existing MySQL database(s)!\n" 1492 | echo -e "This will stop Tomcat from running while the process completes.\n" 1493 | read -p "Are you completely certain? (Y/N) : " areyousure 1494 | 1495 | case "$areyousure" in 1496 | 1497 | Y|y) 1498 | # Stop the tomcat service 1499 | echo -e "\nStopping Tomcat service." 1500 | TomcatService stop 1501 | 1502 | echo -e "\nImporting all database files." 1503 | databases=($(find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///')) 1504 | 1505 | for (( i=0; i<${#databases[@]}; i++ )); 1506 | do 1507 | # Work out what the database name is without the .sql.gz on the end of it! 1508 | db="${databases[i]%.sql.gz}" 1509 | 1510 | echo -e "\nDropping existing database for instance: ${databases[i]} " 1511 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "drop database $db;" 2>/dev/null 1512 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "create database $db;" 2>/dev/null 1513 | 1514 | echo -e "\nImporting database: ${databases[i]}" 1515 | gzip -dc < $rootwarloc/${databases[i]} | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db 2>/dev/null 1516 | 1517 | echo -e "\nRe-establishing grants for database: ${databases[i]}" 1518 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $db.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null 1519 | 1520 | echo -e "\nRepair and Optimise uploaded database: ${databases[i]}" 1521 | mysqlcheck -h$mysqlserveraddress -u$mysqluser -p$mysqlpw --auto-repair --optimize $db 2>&1 1522 | done 1523 | 1524 | # Recalculate memory usage since we've made changes 1525 | ConfigureMemoryUsage 1526 | 1527 | return 1528 | ;; 1529 | 1530 | *) 1531 | echo -e "\nSkipping database restoration" 1532 | return 1 1533 | ;; 1534 | 1535 | esac 1536 | fi 1537 | 1538 | # Does this name already exist?. 1539 | backups=($(find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///')) 1540 | [[ " ${backups[@]} " =~ " $dbname " ]] && found=true || found=false 1541 | 1542 | if [[ $found = false ]]; 1543 | then 1544 | echo -e "\nIncorrect or missing database filename." 1545 | return 1 1546 | fi 1547 | 1548 | # It does exist. Are they sure? Very very very VERY sure? 1549 | 1550 | echo -e "\nWARNING: This will overwrite any existing MySQL database(s)!\n" 1551 | echo -e "This will stop Tomcat from running while the process completes.\n" 1552 | read -p "Are you completely certain? (Y/N) : " areyousure 1553 | 1554 | case "$areyousure" in 1555 | 1556 | Y|y) 1557 | # Stop the tomcat service 1558 | echo -e "\nStopping Tomcat service." 1559 | TomcatService stop 1560 | 1561 | # Work out what the database name is without the .sql.gz on the end of it! 1562 | db="${dbname%.sql.gz}" 1563 | 1564 | echo -e "\nDropping existing database for instance: $dbname " 1565 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "drop database $db;" 2>/dev/null 1566 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "create database $db;" 2>/dev/null 1567 | 1568 | # Upload the selected database dump 1569 | echo -e "\nImporting database: $dbname" 1570 | gzip -dc < $rootwarloc/$dbname | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db 1571 | 1572 | echo -e "\nRe-establishing grants for database: $dbname" 1573 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $db.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null 1574 | 1575 | echo -e "\nRepair and Optimise uploaded database: ${databases[i]}" 1576 | mysqlcheck -h$mysqlserveraddress -u$mysqluser -p$mysqlpw --auto-repair --optimize $db 2>/dev/null 1577 | 1578 | # Recalculate memory usage since we've made changes 1579 | ConfigureMemoryUsage 1580 | ;; 1581 | 1582 | *) 1583 | echo -e "\nSkipping database restoration" 1584 | ;; 1585 | 1586 | esac 1587 | } 1588 | 1589 | UpgradeInstance() 1590 | { 1591 | # Check for presence of Tomcat and MySQL before proceeding 1592 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 1593 | CheckMySQL 1594 | 1595 | if [[ $tomcat = "no" || $mysql = "no" ]]; 1596 | then 1597 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again." 1598 | return 1 1599 | fi 1600 | 1601 | # Call function to show all directory names in the tomcat webapps folder 1602 | InstanceList 1603 | 1604 | # Prompt for the instance name. 1605 | echo -e "\n" 1606 | read -p "Please enter a JSS instance to upgrade (or enter to skip) : " instance 1607 | 1608 | # Does this name already exist?. 1609 | webapps=($(find $webapploc/* -maxdepth 0 -type d | sed -r 's/^.+\///')) 1610 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false 1611 | 1612 | if [[ $found = false ]]; 1613 | then 1614 | echo -e "\nInstance name does not exist." 1615 | return 1 1616 | fi 1617 | 1618 | # It does exist. Are they sure? Very very very VERY sure? 1619 | echo -e "\nWARNING: This will restart the Tomcat service!\n" 1620 | echo -e "\nThe upgrade will be performed with the ROOT.war file located in $rootwarloc " 1621 | read -p "Are you completely certain? (Y/N) : " areyousure 1622 | 1623 | case "$areyousure" in 1624 | 1625 | Y|y) 1626 | # Stop the tomcat service 1627 | echo -e "\nStopping Tomcat service." 1628 | TomcatService stop 1629 | 1630 | # Backup the /WEB-INF/xml/DataBase.xml file 1631 | echo -e "\nBacking up DataBase.xml of instance: $instance" 1632 | cp $webapploc/$instance/$DataBaseLoc/DataBase.xml /tmp 1633 | 1634 | # Delete the tomcat ROOT.war folder 1635 | echo -e "\nDeleting Tomcat instance: $instance" 1636 | rm $webapploc/$instance.war 1637 | rm -rf $webapploc/$instance 1638 | 1639 | # Rename, copy and expand the replacement tomcat ROOT.war file 1640 | echo -e "\nReplacing Tomcat instance: $instance" 1641 | cp $rootwarloc/ROOT.war $webapploc/$instance.war && unzip -oq $webapploc/$instance.war -d $webapploc/$instance 1642 | 1643 | # Wait for allow Tomcat to expand the .war file we copied over. 1644 | echo -e "\nWaiting for .war file to be expanded" 1645 | while [ ! -d "$webapploc/$instance" ] 1646 | do 1647 | echo -e "Awaiting Tomcat to expand instance: $instance" 1648 | sleep 3 1649 | done 1650 | sleep 5 1651 | 1652 | # Modify the log4j file inside the new instance to point to the right files/folders 1653 | echo -e "\nModifying new instance: $instance to point to new log files" 1654 | if [[ $instance = "ROOT" ]]; 1655 | then 1656 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1657 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1658 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1659 | else 1660 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/$instance/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1661 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/$instance/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1662 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/$instance/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties 1663 | fi 1664 | 1665 | # Copy back the DataBase.xml file 1666 | echo -e "\nCopying back DataBase.xml of instance: $instance" 1667 | mv -f /tmp/DataBase.xml $webapploc/$instance/$DataBaseLoc 1668 | 1669 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen! 1670 | chown -R $user:$user $webapploc/ 1671 | 1672 | # Restart tomcat 1673 | echo -e "\nRestarting Tomcat service" 1674 | TomcatService restart 1675 | ;; 1676 | 1677 | *) 1678 | echo -e "\nSkipping upgrade of instance" 1679 | ;; 1680 | 1681 | esac 1682 | } 1683 | 1684 | UpgradeAllInstances() { 1685 | # Check for presence of Tomcat and MySQL before proceeding 1686 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no" 1687 | CheckMySQL 1688 | 1689 | if [[ $tomcat = "no" || $mysql = "no" ]]; 1690 | then 1691 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again." 1692 | return 1 1693 | fi 1694 | 1695 | # It does exist. Are they sure? Very very very VERY sure? 1696 | echo -e "\nWARNING: This will restart the Tomcat service and upgrade ALL JSS instances!" 1697 | echo -e "\nThe upgrade will be performed with the ROOT.war file located in $rootwarloc " 1698 | read -p "Are you completely certain you wish to upgrade ALL instances? (Y/N) : " areyousure 1699 | 1700 | case "$areyousure" in 1701 | 1702 | Y|y) 1703 | # Grab an array containing all current JSS instances for processing. 1704 | webapps=($(find $webapploc/* -maxdepth 0 -type d | sed -r 's/^.+\///')) 1705 | 1706 | # Stop the tomcat service 1707 | echo -e "\nStopping Tomcat service.\n" 1708 | TomcatService stop 1709 | 1710 | # Start the upgrade processing loop here. 1711 | for (( i=0; i<${#webapps[@]}; i++ )); 1712 | do 1713 | 1714 | # Line feed for clarity 1715 | echo -e "\n" 1716 | 1717 | # Backup the /WEB-INF/xml/DataBase.xml file 1718 | echo -e "Backing up DataBase.xml of instance: ${webapps[i]}" 1719 | mv $webapploc/${webapps[i]}/$DataBaseLoc/DataBase.xml /tmp 1720 | 1721 | # Delete the tomcat ROOT.war folder 1722 | echo -e "Deleting Tomcat instance: ${webapps[i]}" 1723 | rm $webapploc/${webapps[i]}.war 1724 | rm -rf $webapploc/${webapps[i]} 1725 | 1726 | # Rename, copy and expand the replacement tomcat ROOT.war file 1727 | echo -e "Replacing Tomcat instance: ${webapps[i]}" 1728 | cp $rootwarloc/ROOT.war $webapploc/${webapps[i]}.war && unzip -oq $webapploc/${webapps[i]}.war -d $webapploc/${webapps[i]} 1729 | 1730 | # Wait for allow Tomcat to expand the .war file we copied over. 1731 | echo -e "\nWaiting for the .war file to be expanded" 1732 | while [ ! -d '$rootwarloc/$instance' ] 1733 | do 1734 | sleep 1 1735 | done 1736 | sleep 5 1737 | 1738 | # Modify the log4j file inside the new instance to point to the right files/folders 1739 | echo -e "\nModifying new instance: $instance to point to new log files" 1740 | if [[ $instance = "ROOT" ]]; 1741 | then 1742 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1743 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1744 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1745 | else 1746 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/${webapps[i]}/JAMFChangeManagement.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1747 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/${webapps[i]}/JAMFSoftwareServer.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1748 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/${webapps[i]}/JSSAccess.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties 1749 | fi 1750 | 1751 | # Copy back the DataBase.xml file 1752 | echo -e "Copying back DataBase.xml of instance: ${webapps[i]}" 1753 | mv -f /tmp/DataBase.xml $webapploc/${webapps[i]}/$DataBaseLoc/ 1754 | 1755 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen! 1756 | chown -R $user:$user $webapploc/ 1757 | 1758 | # Loop finishes here 1759 | done 1760 | 1761 | # Restart tomcat 1762 | echo -e "\nRestarting Tomcat service\n" 1763 | TomcatService restart 1764 | ;; 1765 | 1766 | *) 1767 | echo -e "\nSkipping upgrade of instance" 1768 | ;; 1769 | 1770 | esac 1771 | } 1772 | 1773 | MainMenu() 1774 | { 1775 | # Set IFS to only use new lines as field separator. 1776 | IFS=$'\n' 1777 | 1778 | # Clear Screen 1779 | clear 1780 | 1781 | # Start menu screen here 1782 | echo -e "\n----------------------------------------" 1783 | echo -e "\n JSS in a Box" 1784 | echo -e "\n----------------------------------------" 1785 | echo -e " Version $currentver - $currentverdate" 1786 | echo -e "----------------------------------------\n" 1787 | 1788 | while [[ $choice != "q" ]] 1789 | do 1790 | echo -e "\nMain Menu\n" 1791 | echo -e "1) Check & Install Server Software" 1792 | echo -e "2) Show list of current JSS instances" 1793 | echo -e "3) Create new JSS & Database Instance" 1794 | echo -e "4) Delete existing JSS & Database Instance" 1795 | echo -e "5) Dump MySQL Database to file" 1796 | echo -e "6) Upload MySQL dump to database" 1797 | echo -e "7) Upgrade a single JSS instance" 1798 | echo -e "8) Upgrade ALL JSS instances" 1799 | echo -e "9) Refresh SSL certificates from CA" 1800 | echo -e "q) Exit Script\n" 1801 | 1802 | read -p "Choose an option (1-9 / q) : " choice 1803 | 1804 | case "$choice" in 1805 | 1) 1806 | InitialiseServer ;; 1807 | 2) 1808 | InstanceList ;; 1809 | 3) 1810 | CreateNewInstance ;; 1811 | 4) 1812 | DeleteInstance ;; 1813 | 5) 1814 | DumpDatabase ;; 1815 | 6) 1816 | UploadDatabase ;; 1817 | 7) 1818 | UpgradeInstance ;; 1819 | 8) 1820 | UpgradeAllInstances ;; 1821 | 9) 1822 | UpdateLeSSLKeys ;; 1823 | q) 1824 | echo -e "\nThank you for using JSS in a Box!" 1825 | ;; 1826 | *) 1827 | echo -e "\nIncorrect input. Please try again." ;; 1828 | esac 1829 | 1830 | done 1831 | } 1832 | 1833 | ## Main Code Begins here! 1834 | 1835 | # Check for distribution, user privilege level and required files 1836 | 1837 | WhichDistAmI 1838 | AmIroot 1839 | IsROOTwarPresent 1840 | UpdatePkgMgr 1841 | PrepDBfile 1842 | 1843 | # Parameter checking code here. 1844 | 1845 | case "$1" in 1846 | -d|--dump) 1847 | DumpDatabase 1848 | exit 0 1849 | ;; 1850 | 1851 | -i|--instance) 1852 | InstanceList 1853 | exit 0 1854 | ;; 1855 | 1856 | -u|--upgrade) 1857 | UpgradeAllInstances 1858 | exit 0 1859 | ;; 1860 | 1861 | -s|--ssl) 1862 | UpdateLeSSLKeys 1863 | exit 0 1864 | ;; 1865 | 1866 | -h|--help) 1867 | echo -e "\nJSS in a Box" 1868 | echo -e "Version $currentver - $currentverdate" 1869 | echo -e "\nUsage: sudo ./jss-in-a-box.sh