├── .github └── FUNDING.yml ├── README.md └── auto_script └── masto_auto_script.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: https://www.paypal.com/donate/?hosted_button_id=HV5ETC3R5VM4E 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Automate your Mastodon installation using this deployment script powered by Docker and Bash. Enhance the security of your Mastodon instance with just one command. 2 | 3 | Whether you're working with a fresh server or an existing setup, this script is designed for both new and veteran Mastodon admins. 4 | 5 | ## Features 6 | 7 | - 🚀 One-command deployment. 8 | - 🔐 Enhancements to server security (SSH port change, firewall setup, Fail2Ban integration). 9 | - 📘 Open-source and redistributable (a credit and shout out to Honeytree Technologies is greatly appreciated). 10 | 11 | ## Script Details 12 | 13 | - **Language**: Bash 14 | - **Deployment**: Docker-based Mastodon installation. 15 | - **Configuration Options**: 16 | - Elasticsearch deployment (off by default). 17 | - Adjustable Postgres DB size (default: 256MB). 18 | - Automatic SSL certificate creation using Let's Encrypt along with Nginx configuration. 19 | 20 | ## Requirements 21 | 22 | - Server or VPS with minimum 4GB RAM, 2 vCPU, and 65 GB storage. 23 | - Ubuntu v20.04 LTS. 24 | - Open ports: 443, 80 and SSH (Which you will choose in the script). 25 | - Active internet connection to fetch packages and Docker images. 26 | - Domain name pointing to the server's IP address (necessary for SSL certification). 27 | - An email delivery service or SMTP server. 28 | 29 | ## Installation Steps 30 | 31 | 1. SSH into the machine and assume root privileges. 32 | 2. Create and navigate to a directory: `mkdir auto_script && cd auto_script`. 33 | You can also use own directory. 34 | 3. Run the following command to start the script. 35 | ```bash 36 | curl -sSL https://code.honeytreetech.com/fediverse/mastodon/auto-installer/masto_auto_script.sh -o ./masto_auto_script.sh && sudo chmod +x masto_auto_script.sh && ./masto_auto_script.sh 37 | ``` 38 | 4. Follow further on-screen instructions to complete the setup. 39 | 5. You will be prompted for installation details per the following table. 40 | | Name | Description | Mandatory | Optional | Default Value | 41 | |------|---------|-----------|----------|---------------| 42 | | `admin_user`|Admin user name| ✓ | ✖| ✖ | 43 | |`admin_email` | Admin email| ✓| ✖| ✖| 44 | |`domain_name` | Domain name| ✓| ✖| ✖| 45 | |`db_size` | Database size | ✖| ✓| 256 MB | 46 | |`es_status` | elasticsearch service choice (`yes`/`no`)| ✓| ✖| ✖| 47 | |`smtp_server` | SMTP server| ✓| ✖| ✖| 48 | |`smtp_port` | SMTP port| ✓| ✖| ✖| 49 | |`smtp_login` | SMTP login| ✓| ✖| ✖| 50 | |`smtp_password` | SMTP password| ✓| ✖| ✖| 51 | |`smtp_from_address` | SMTP from address| ✓| ✖| ✖| 52 | |`db_user` | Database user| ✖| ✓|postgres | 53 | |`db_password` | Database Password| ✖| ✓|pass_XXXXXXXXX (whereX is Random character) | 54 | |`db_name` | Database name| ✖| ✓|masto_XXXXXXXXX (whereX is Random character) | 55 | |`es_user` | Elasticsearch user name| ✖| ✓|masto_XXXXXXXXX (whereX is Random character) | 56 | |`es_password` | Elasticsearch password| ✖| ✓|pass_XXXXXXXXX (whereX is Random character) | 57 | |`port` | SSH port | ✓| ✖| ✖| 58 | 59 | 60 | 5. Accept terms of service as prompted. 61 | 6. Follow further on-screen instructions to complete the setup. 62 | 63 | ## Post Deployment 64 | 65 | - Access Mastodon via the provided domain with the given admin credentials. 66 | - SSH port defaults to new port (which you entered in the script). 67 | - fail2ban is activated with progressive blocking. 68 | 69 | ## Post-Installation Security Recommendations 70 | 71 | Once you have successfully deployed Mastodon using this script, it's crucial to take additional steps to secure and harden your environment. 72 | 73 | Consider the following actions: 74 | 75 | - **Regular Updates**: Ensure that all system packages and software are regularly updated to patch potential vulnerabilities. 76 | - **Firewall Configuration**: Fine-tune your firewall settings to allow only necessary traffic and block potential threats. 77 | - **User Access**: Limit or disable root access. Use sudo for administrative tasks and avoid using the root account for daily tasks. 78 | - **Secure Passwords**: Implement strong password policies, and consider using password managers. 79 | - **Two-Factor Authentication**: Where possible, enable 2FA for critical services and accounts. 80 | - **Backup**: Regularly back up critical data and ensure backups are stored securely. 81 | - **Monitoring & Logging**: Set up monitoring and logging to detect and alert on suspicious activities. 82 | - **Application-Specific Security**: Explore and implement security best practices specifically tailored to Mastodon and any other applications you might be running. 83 | - **Review and Audit**: Periodically review and audit your security settings and practices to ensure they are up-to-date with the latest threats and vulnerabilities. 84 | 85 | It's essential to recognize that the security landscape is dynamic. Stay informed, and be proactive in securing your digital assets. 86 | 87 | ## Troubleshooting 88 | ### Known Issues 89 | 90 | 1. **Error**: "Could not get lock /var/lib/dpkg/lock-frontend..." 91 | - **Cause**: `unattended-upgr` process. 92 | - **Fix**: 93 | 94 | ```bash 95 | sudo rm /var/lib/dpkg/lock-frontend 96 | ``` 97 | Then, restart the script and pick an SSL certificate option: 98 | a. Try reinstalling the current certificate. 99 | b. Renew & replace the certificate. 100 | 101 | ## Disclaimer 102 | Using the installer is solely at your own risk, and you are responsible for any issues regarding quality, performance, accuracy, and effort. Additionally, support is only available to managed services clients of [Honeytree Technologies, LLC](https://honeytreetech.com); no free support is provided. 103 | 104 | ## Credits 105 | 106 | A big thank you to [Honeytree Technologies, LLC](https://honeytreetech.com) for making this script possible. 107 | 108 | Stay connected with us on Mastodon: [@jeff@honeytree.social](https://honeytree.social/@jeff). 109 | -------------------------------------------------------------------------------- /auto_script/masto_auto_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Display the script header, providing basic information about the script. 3 | echo "######################################################################" 4 | echo "# #" 5 | echo "# Mastodon Installation and Hardening Script #" 6 | echo "# #" 7 | echo "# Created by Honeytree Technologies, LLC #" 8 | echo "# www.honeytreetech.com #" 9 | echo "# #" 10 | echo "# Mastodon: honeytree.social #" 11 | echo "# Email: info@honeytreetech.com #" 12 | echo "# #" 13 | echo "######################################################################" 14 | 15 | # Pause the script for 3 seconds to allow the user to read the header 16 | sleep 3 17 | 18 | # Display more detailed information about what each option does 19 | echo "########################################################################" 20 | echo "##### THIS IS IMPORTANT, PLEASE READ CAREFULLY BEFORE SELECTING #####" 21 | echo "##### #####" 22 | echo "##### This will install Mastodon on fresh server. #####" 23 | echo "##### #####" 24 | echo "##### Installing on an operating Mastodon server will wipe data. #####" 25 | echo "##### #####" 26 | echo "########################################################################" 27 | 28 | # Pause the script for 3 seconds to allow the user to read the warning 29 | sleep 3 30 | 31 | # Function to generate a random character 32 | function random_char() { 33 | local chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 34 | echo -n "${chars:RANDOM%${#chars}:1}" 35 | } 36 | 37 | # Function to generate a random string of a given length 38 | function random_string() { 39 | local length=$1 40 | local result="" 41 | for ((i = 0; i < length; i++)); do 42 | result="${result}$(random_char)" 43 | done 44 | echo -n "$result" 45 | } 46 | 47 | # Function to validate if the port number is within the specified range 48 | validate_port() { 49 | local port=$1 50 | local excluded_ports=("80" "443" "3000") 51 | 52 | if [[ $port =~ ^[0-9]+$ && $port -ge 0 && $port -le 65536 ]]; then 53 | for excluded_port in "${excluded_ports[@]}"; do 54 | if [ "$port" -eq "$excluded_port" ]; then 55 | return 2 # Excluded port 56 | fi 57 | done 58 | return 0 # Valid port number 59 | else 60 | return 1 # Invalid port number 61 | fi 62 | } 63 | 64 | while true; do 65 | read -p "Enter admin user name: " admin_user 66 | if [ -n "$admin_user" ]; then 67 | break 68 | else 69 | echo "Admin name cannot be empty. Please enter admin name." 70 | fi 71 | done 72 | 73 | while true; do 74 | read -p "Enter admin email: " admin_email 75 | if [ -n "$admin_email" ]; then 76 | break 77 | else 78 | echo "Admin email cannot be empty. Please enter admin email." 79 | fi 80 | done 81 | 82 | while true; do 83 | read -p "Enter valid domain name: " domain_name 84 | if [ -n "$domain_name" ]; then 85 | break 86 | else 87 | echo "Domain cannot be empty. Please enter domain." 88 | fi 89 | done 90 | 91 | while true; do 92 | read -p "Enter the postgres db size in mb (Default: 256mb): " db_size 93 | # set default value if value not present 94 | if [ -z ${db_size} ] ; then 95 | db_size=256 96 | fi 97 | # Check if input is numeric 98 | if [[ "${db_size}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then 99 | break # Exit the loop if input is numeric 100 | else 101 | echo "Invalid input. Please enter numerical value." 102 | fi 103 | done 104 | echo "Your db_size is, $db_size" 105 | 106 | # choice for elastic search service 107 | while true; do 108 | read -p "Do you want elasticsearch service (yes/no): " choice 109 | case "$choice" in 110 | [Yy]*) 111 | es_status=true 112 | break 113 | ;; 114 | [Nn]*) 115 | es_status=false 116 | break 117 | ;; 118 | *) 119 | echo "Invalid input. Please enter 'yes' or 'no'." 120 | ;; 121 | esac 122 | done 123 | 124 | while true; do 125 | read -p "Enter SMTP SERVER: " smtp_server 126 | if [ -n "$smtp_server" ]; then 127 | break 128 | else 129 | echo "SMTP SERVER cannot be empty. Please enter smtp server." 130 | fi 131 | done 132 | 133 | while true; do 134 | read -p "Enter SMTP PORT: " smtp_port 135 | if [ -n "$smtp_port" ]; then 136 | 137 | break 138 | else 139 | echo "SMTP PORT cannot be empty. Please enter smtp port." 140 | fi 141 | done 142 | 143 | while true; do 144 | read -p "Enter SMTP LOGIN: " smtp_login 145 | if [ -n "$smtp_login" ]; then 146 | break 147 | else 148 | echo "SMTP LOGIN cannot be empty. Please enter smtp_login." 149 | fi 150 | done 151 | 152 | while true; do 153 | read -p "Enter SMTP_PASSWORD: " smtp_password 154 | if [ -n "$smtp_password" ]; then 155 | break 156 | else 157 | echo "SMTP_PASSWORD cannot be empty. Please enter smtp password." 158 | fi 159 | done 160 | 161 | while true; do 162 | read -p "Enter SMTP FROM ADDRESS: " smtp_from_address 163 | if [ -n "$smtp_from_address" ]; then 164 | break 165 | else 166 | echo "SMTP FROM ADDRESS cannot be empty. Please enter smtp from address." 167 | fi 168 | done 169 | 170 | 171 | read -p "Enter the DB USER NAME (Default: postgres): " db_user 172 | if [ -z ${db_user} ] ; then 173 | db_user=postgres 174 | fi 175 | 176 | temp_password="pass_$(random_string 16)" 177 | read -p "Enter the DB PASSWORD (Default: ${temp_password}): " db_password 178 | if [ -z ${db_password} ] ; then 179 | db_password=${temp_password} 180 | fi 181 | echo "your db password is ${db_password}" 182 | temp_db="masto_$(random_string 8)" 183 | read -p "Enter the DB NAME (Default: ${temp_db}): " db_name 184 | if [ -z ${db_name} ] ; then 185 | db_name=${temp_db} 186 | fi 187 | echo "Your db name is ${db_name}" 188 | 189 | read -p "Enter the ELASTIC SEARCH USER (Default: elastic): " es_user 190 | if [ -z ${es_user} ] ; then 191 | es_user=elastic 192 | fi 193 | e_temp_password="pass_$(random_string 16)" 194 | read -p "Enter the ELASTIC SEARCH PASSWORD (Default: ${e_temp_password}): " es_password 195 | if [ -z ${es_password} ] ; then 196 | es_password=${e_temp_password} 197 | fi 198 | 199 | # Prompt the user until a valid port is entered 200 | while true; do 201 | read -p "Enter a port number (1-65535, excluding 80, 443, and 3000): " port 202 | # Validate the input 203 | validate_port "$port" 204 | case $? in 205 | 0) 206 | echo "SSH port will be: $port" 207 | ssh_port=$port 208 | break # Exit the loop as a valid port has been entered 209 | ;; 210 | 1) 211 | echo "Invalid port number. Please enter a valid port number between 1 and 65535." 212 | ;; 213 | 2) 214 | echo "Invalid port number. Port $port is excluded. Please choose a different port." 215 | ;; 216 | esac 217 | done 218 | 219 | # Remove old docker container if docker already present 220 | if docker -v &>/dev/null; then 221 | sudo docker rm -f $(docker ps -a -q) 222 | fi 223 | 224 | # install new version of docker 225 | sudo apt-get update -y 226 | sudo apt-get install -y ca-certificates curl gnupg lsb-release 227 | if test -f /usr/share/keyrings/docker-archive-keyring.gpg; then 228 | sudo rm /usr/share/keyrings/docker-archive-keyring.gpg 229 | fi 230 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg 231 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 232 | sudo apt-get update -y 233 | sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin 234 | 235 | # assign work directory 236 | work_dir=~/mastodon 237 | # Remove old work directory if present 238 | sudo rm -rf ${work_dir} 239 | # Make new work directory 240 | mkdir ${work_dir} 241 | 242 | # create blank a enviromental files for Mastodon 243 | touch ${work_dir}/.env.es 244 | touch ${work_dir}/.env.mastodon 245 | touch ${work_dir}/docker-compose.yml 246 | touch ${work_dir}/.env.db 247 | 248 | # add content in the docker-compose file 249 | cat <>${work_dir}/docker-compose.yml 250 | version: '3' 251 | 252 | networks: 253 | 254 | external_network: 255 | 256 | internal_network: 257 | 258 | internal: true 259 | 260 | services: 261 | 262 | db: 263 | 264 | restart: always 265 | 266 | image: postgres:14-alpine 267 | 268 | shm_size: ${db_size}mb 269 | 270 | networks: 271 | 272 | - internal_network 273 | 274 | healthcheck: 275 | 276 | test: [ 'CMD', 'pg_isready', '-U', 'postgres' ] 277 | 278 | volumes: 279 | 280 | - ./data/postgres:/var/lib/postgresql/data 281 | 282 | environment: 283 | 284 | - 'POSTGRES_HOST_AUTH_METHOD=trust' 285 | 286 | env_file: 287 | 288 | - .env.db 289 | 290 | redis: 291 | 292 | restart: always 293 | 294 | image: redis:7-alpine 295 | 296 | networks: 297 | 298 | - internal_network 299 | 300 | healthcheck: 301 | 302 | test: [ 'CMD', 'redis-cli', 'ping' ] 303 | 304 | volumes: 305 | 306 | - ./data/redis:/data 307 | 308 | es: 309 | 310 | restart: always 311 | 312 | image: docker.elastic.co/elasticsearch/elasticsearch:7.17.8 313 | 314 | environment: 315 | 316 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true" 317 | 318 | - "xpack.license.self_generated.type=basic" 319 | 320 | - "xpack.security.enabled=false" 321 | 322 | - "xpack.watcher.enabled=false" 323 | 324 | - "xpack.graph.enabled=false" 325 | 326 | - "xpack.ml.enabled=false" 327 | 328 | - "bootstrap.memory_lock=true" 329 | 330 | - "cluster.name=mastodon-es" 331 | 332 | - "discovery.type=single-node" 333 | 334 | - "thread_pool.write.queue_size=1000" 335 | 336 | env_file: 337 | 338 | - .env.es 339 | 340 | networks: 341 | 342 | - external_network 343 | 344 | - internal_network 345 | 346 | healthcheck: 347 | 348 | test: 349 | 350 | [ 351 | 352 | "CMD-SHELL", 353 | 354 | "curl --silent --fail localhost:9200/_cluster/health || exit 1" 355 | 356 | ] 357 | 358 | volumes: 359 | 360 | - /opt/mastodon/data/elasticsearch:/usr/share/elasticsearch/data 361 | 362 | ulimits: 363 | 364 | memlock: 365 | 366 | soft: -1 367 | 368 | hard: -1 369 | 370 | nofile: 371 | 372 | soft: 65536 373 | 374 | hard: 65536 375 | 376 | ports: 377 | 378 | - '127.0.0.1:9200:9200' 379 | 380 | 381 | 382 | console: 383 | 384 | image: tootsuite/mastodon:latest 385 | 386 | env_file: .env.mastodon 387 | 388 | command: /bin/bash 389 | 390 | restart: "no" 391 | 392 | depends_on: 393 | 394 | - db 395 | 396 | - redis 397 | 398 | networks: 399 | 400 | - internal_network 401 | 402 | - external_network 403 | 404 | volumes: 405 | 406 | - ./data/public/system:/mastodon/public/system 407 | 408 | web: 409 | 410 | image: tootsuite/mastodon:latest 411 | 412 | restart: always 413 | 414 | env_file: .env.mastodon 415 | 416 | command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" 417 | 418 | networks: 419 | 420 | - internal_network 421 | 422 | - external_network 423 | 424 | healthcheck: 425 | 426 | # prettier-ignore 427 | 428 | test: 429 | 430 | [ 431 | 432 | 'CMD-SHELL', 433 | 434 | 'wget -q --spider --proxy=off localhost:3000/health || exit 1' 435 | 436 | ] 437 | 438 | ports: 439 | 440 | - '127.0.0.1:3000:3000' 441 | 442 | depends_on: 443 | 444 | - db 445 | 446 | - redis 447 | 448 | - es 449 | 450 | volumes: 451 | 452 | - ./data/public/system:/mastodon/public/system 453 | 454 | 455 | 456 | streaming: 457 | 458 | image: tootsuite/mastodon:latest 459 | 460 | restart: always 461 | 462 | env_file: .env.mastodon 463 | 464 | command: node ./streaming 465 | 466 | networks: 467 | 468 | - external_network 469 | 470 | - internal_network 471 | 472 | healthcheck: 473 | 474 | # prettier-ignore 475 | 476 | test: 477 | 478 | [ 479 | 480 | 'CMD-SHELL', 481 | 482 | 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1' 483 | 484 | ] 485 | 486 | ports: 487 | 488 | - '127.0.0.1:4000:4000' 489 | 490 | depends_on: 491 | 492 | - db 493 | 494 | - redis 495 | 496 | sidekiq: 497 | 498 | image: tootsuite/mastodon:latest 499 | 500 | restart: always 501 | 502 | env_file: .env.mastodon 503 | 504 | command: bundle exec sidekiq 505 | 506 | networks: 507 | 508 | - external_network 509 | 510 | - internal_network 511 | 512 | volumes: 513 | 514 | - ./data/public/system:/mastodon/public/system 515 | 516 | healthcheck: 517 | 518 | test: [ 'CMD-SHELL', "ps aux | grep '[s]idekiq 6' || false" ] 519 | 520 | depends_on: 521 | 522 | - db 523 | 524 | - redis 525 | docker_content 526 | 527 | # Add content in the.env.db file 528 | cat <> ${work_dir}/.env.db 529 | POSTGRES_USER=postgres 530 | POSTGRES_PASSWORD=postgres 531 | db_env 532 | 533 | # Add content in the .env.es file 534 | cat <> ${work_dir}/.env.es 535 | ELASTIC_PASSWORD=password 536 | es_env 537 | 538 | #Generate secret keys 539 | secret1=$(docker compose -f ${work_dir}/docker-compose.yml run --rm console bundle exec rake secret) 540 | secret2=$(docker compose -f ${work_dir}/docker-compose.yml run --rm console bundle exec rake secret) 541 | keys=$(docker compose -f ${work_dir}/docker-compose.yml run --rm console bundle exec rake mastodon:webpush:generate_vapid_key) 542 | vapid_private_key=$(echo "$keys" | grep -o 'VAPID_PRIVATE_KEY=[^ ]*' | cut -d'=' -f2)= 543 | vapid_public_key=$(echo "$keys" | grep -o 'VAPID_PUBLIC_KEY=[^ ]*' | cut -d'=' -f2)= 544 | 545 | # Add content in the .env.mastodon 546 | cat <> ${work_dir}/.env.mastodon 547 | LOCAL_DOMAIN=${domain_name} 548 | REDIS_HOST=redis 549 | REDIS_PORT=6379 550 | DB_HOST=db 551 | DB_USER=${db_user} 552 | DB_NAME=${db_name} 553 | DB_PASS=${db_password} 554 | DB_PORT=5432 555 | ES_ENABLED=${es_status} 556 | ES_HOST=es 557 | ES_PORT=9200 558 | ES_USER=${es_user} 559 | ES_PASS=${es_password} 560 | SECRET_KEY_BASE=${secret1} 561 | OTP_SECRET=${secret2} 562 | VAPID_PRIVATE_KEY=${vapid_private_key} 563 | VAPID_PUBLIC_KEY=${vapid_public_key} 564 | SMTP_SERVER=${smtp_server} 565 | SMTP_PORT=${smtp_port} 566 | SMTP_LOGIN=${smtp_login} 567 | SMTP_PASSWORD=${smtp_password} 568 | SMTP_FROM_ADDRESS=${smtp_from_address} 569 | S3_ENABLED=false 570 | S3_BUCKET= 571 | AWS_ACCESS_KEY_ID= 572 | AWS_SECRET_ACCESS_KEY= 573 | S3_ALIAS_HOST= 574 | IP_RETENTION_PERIOD=31556952 575 | SESSION_RETENTION_PERIOD=31556952 576 | mastodon_env 577 | 578 | # start the PostgreSQL container 579 | docker compose -f ${work_dir}/docker-compose.yml up -d db 580 | 581 | # Start the Elasticsearch container and make data directory. 582 | if [ "$es_status" = true ]; then 583 | sudo mkdir -p ${work_dir}/data/elasticsearch 584 | sudo chown -R 1000:1000 ${work_dir}/data/elasticsearch 585 | docker compose -f ${work_dir}/docker-compose.yml up -d es 586 | fi 587 | 588 | # increase the max_map_count 589 | sudo sysctl -w vm.max_map_count=262144 590 | 591 | 592 | 593 | # Make Database setup 594 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bundle exec rake db:setup 595 | 596 | # Start Mastadon application. 597 | docker compose -f ${work_dir}/docker-compose.yml up -d 598 | 599 | # Setting up the nginx 600 | 601 | if nginx -v &>/dev/null; then 602 | echo "Nginx is already install installed" 603 | rm /etc/nginx/sites-available/mastodon 604 | rm /etc/nginx/sites-enabled/mastodon 605 | else 606 | sudo apt-get update 607 | sudo apt-get install -y nginx 608 | fi 609 | 610 | # make the nginx file for the application 611 | touch /etc/nginx/sites-available/mastodon 612 | cat <>/etc/nginx/sites-available/mastodon 613 | server { 614 | 615 | server_name ${domain_name}; 616 | 617 | 618 | 619 | proxy_set_header Host \$host; 620 | 621 | proxy_set_header X-Real-IP \$remote_addr; 622 | 623 | proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; 624 | 625 | proxy_set_header X-Forwarded-Proto \$scheme; 626 | 627 | proxy_set_header Proxy ""; 628 | 629 | proxy_http_version 1.1; 630 | 631 | proxy_set_header Upgrade \$http_upgrade; 632 | 633 | proxy_set_header Connection "upgrade"; 634 | 635 | 636 | 637 | location / { 638 | 639 | proxy_pass http://localhost:3000; 640 | 641 | proxy_pass_header Server; 642 | 643 | 644 | 645 | proxy_buffering on; 646 | 647 | proxy_redirect off; 648 | 649 | } 650 | 651 | 652 | 653 | location ^~ /api/v1/streaming { 654 | 655 | 656 | 657 | proxy_pass http://localhost:4000; 658 | 659 | proxy_buffering off; 660 | 661 | proxy_redirect off; 662 | 663 | } 664 | 665 | } 666 | nginx_content 667 | 668 | # Link to sites-enabled to enable the virtual host. 669 | sudo ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/ 670 | 671 | # Reload the nginx service. 672 | sudo systemctl restart nginx 673 | 674 | # Config ufw firewall to allow Nginx ports. Skip if your server doesn't have ufw. 675 | sudo ufw allow 'Nginx Full' 676 | 677 | # Secure Mastodon with Let's Encrypt SSL 678 | sudo apt-get install -y certbot python3-certbot-nginx 679 | 680 | # Generate the ssl certificate for domain 681 | sudo certbot --nginx -d ${domain_name} 682 | 683 | systemctl restart nginx 684 | 685 | # Enable toolctl toolctl in docker container 686 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl 687 | 688 | # Generate Admin password 689 | admin_password=$(docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl accounts create ${admin_user} --email ${admin_email} --confirmed --role Admin | awk '/password:/{print }') 690 | 691 | # Remove Media files 692 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl media remove 693 | # Remove Preview cards 694 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl preview_cards remove 695 | 696 | # make cron job for Remove Media files and Remove Preview cards 697 | cat <>${work_dir}/auto-cleanup.sh 698 | #!/bin/sh 699 | 700 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl media remove 701 | 702 | docker compose -f ${work_dir}/docker-compose.yml run --rm console bin/tootctl preview_cards remove 703 | make_job 704 | 705 | # Give permission to crontab 706 | sudo chmod +x ${work_dir}/auto-cleanup.sh 707 | 708 | echo "0 0 * * * ${work_dir}/auto-cleanup.sh" | crontab - 709 | 710 | # change ssh port 711 | sudo cp /etc/ssh/ssh_config /etc/ssh/ssh_config_copy 712 | sudo rm /etc/ssh/ssh_config 713 | 714 | cat <> /etc/ssh/ssh_config 715 | Host * 716 | # ForwardAgent no 717 | # ForwardX11 no 718 | # ForwardX11Trusted yes 719 | # PasswordAuthentication yes 720 | # HostbasedAuthentication no 721 | # GSSAPIAuthentication no 722 | # GSSAPIDelegateCredentials no 723 | # GSSAPIKeyExchange no 724 | # GSSAPITrustDNS no 725 | # BatchMode no 726 | # CheckHostIP yes 727 | # AddressFamily any 728 | # ConnectTimeout 0 729 | # StrictHostKeyChecking ask 730 | # IdentityFile ~/.ssh/id_rsa 731 | # IdentityFile ~/.ssh/id_dsa 732 | # IdentityFile ~/.ssh/id_ecdsa 733 | # IdentityFile ~/.ssh/id_ed25519 734 | Port ${ssh_port} 735 | # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc 736 | # MACs hmac-md5,hmac-sha1,umac-64@openssh.com 737 | # EscapeChar ~ 738 | # Tunnel no 739 | # TunnelDevice any:any 740 | # PermitLocalCommand no 741 | # VisualHostKey no 742 | # ProxyCommand ssh -q -W %h:%p gateway.example.com 743 | # RekeyLimit 1G 1h 744 | # UserKnownHostsFile ~/.ssh/known_hosts.d/%k 745 | SendEnv LANG LC_* 746 | HashKnownHosts yes 747 | GSSAPIAuthentication yes 748 | ssh_content 749 | 750 | sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_copy 751 | sudo rm /etc/ssh/sshd_config 752 | 753 | cat <> /etc/ssh/sshd_config 754 | PermitRootLogin yes 755 | 756 | 757 | # This is the sshd server system-wide configuration file. See 758 | # sshd_config(5) for more information. 759 | 760 | # This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games 761 | 762 | # The strategy used for options in the default sshd_config shipped with 763 | # OpenSSH is to specify options with their default value where 764 | # possible, but leave them commented. Uncommented options override the 765 | # default value. 766 | 767 | Include /etc/ssh/sshd_config.d/*.conf 768 | 769 | Port ${ssh_port} 770 | #AddressFamily any 771 | #ListenAddress 0.0.0.0 772 | #ListenAddress :: 773 | 774 | #HostKey /etc/ssh/ssh_host_rsa_key 775 | #HostKey /etc/ssh/ssh_host_ecdsa_key 776 | #HostKey /etc/ssh/ssh_host_ed25519_key 777 | 778 | # Ciphers and keying 779 | #RekeyLimit default none 780 | 781 | # Logging 782 | #SyslogFacility AUTH 783 | #LogLevel INFO 784 | 785 | # Authentication: 786 | 787 | #LoginGraceTime 2m 788 | #PermitRootLogin prohibit-password 789 | #StrictModes yes 790 | #MaxAuthTries 6 791 | #MaxSessions 10 792 | 793 | #PubkeyAuthentication yes 794 | 795 | # Expect .ssh/authorized_keys2 to be disregarded by default in future. 796 | #AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 797 | 798 | #AuthorizedPrincipalsFile none 799 | 800 | #AuthorizedKeysCommand none 801 | #AuthorizedKeysCommandUser nobody 802 | 803 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts 804 | #HostbasedAuthentication no 805 | # Change to yes if you don't trust ~/.ssh/known_hosts for 806 | # HostbasedAuthentication 807 | #IgnoreUserKnownHosts no 808 | # Don't read the user's ~/.rhosts and ~/.shosts files 809 | #IgnoreRhosts yes 810 | 811 | # To disable tunneled clear text passwords, change to no here! 812 | #PasswordAuthentication yes 813 | #PermitEmptyPasswords no 814 | 815 | # Change to yes to enable challenge-response passwords (beware issues with 816 | # some PAM modules and threads) 817 | KbdInteractiveAuthentication no 818 | 819 | # Kerberos options 820 | #KerberosAuthentication no 821 | #KerberosOrLocalPasswd yes 822 | #KerberosTicketCleanup yes 823 | #KerberosGetAFSToken no 824 | 825 | # GSSAPI options 826 | #GSSAPIAuthentication no 827 | #GSSAPICleanupCredentials yes 828 | #GSSAPIStrictAcceptorCheck yes 829 | #GSSAPIKeyExchange no 830 | 831 | # Set this to 'yes' to enable PAM authentication, account processing, 832 | # and session processing. If this is enabled, PAM authentication will 833 | # be allowed through the KbdInteractiveAuthentication and 834 | # PasswordAuthentication. Depending on your PAM configuration, 835 | # PAM authentication via KbdInteractiveAuthentication may bypass 836 | # the setting of "PermitRootLogin without-password". 837 | # If you just want the PAM account and session checks to run without 838 | # PAM authentication, then enable this but set PasswordAuthentication 839 | # and KbdInteractiveAuthentication to 'no'. 840 | UsePAM yes 841 | 842 | #AllowAgentForwarding yes 843 | #AllowTcpForwarding yes 844 | #GatewayPorts no 845 | X11Forwarding yes 846 | #X11DisplayOffset 10 847 | #X11UseLocalhost yes 848 | #PermitTTY yes 849 | PrintMotd no 850 | #PrintLastLog yes 851 | #TCPKeepAlive yes 852 | #PermitUserEnvironment no 853 | #Compression delayed 854 | #ClientAliveInterval 0 855 | #ClientAliveCountMax 3 856 | #UseDNS no 857 | #PidFile /run/sshd.pid 858 | #MaxStartups 10:30:100 859 | #PermitTunnel no 860 | #ChrootDirectory none 861 | #VersionAddendum none 862 | 863 | # no default banner path 864 | #Banner none 865 | 866 | # Allow client to pass locale environment variables 867 | AcceptEnv LANG LC_* 868 | 869 | # override default of no subsystems 870 | Subsystem sftp /usr/lib/openssh/sftp-server 871 | 872 | # Example of overriding settings on a per-user basis 873 | #Match User anoncvs 874 | # X11Forwarding no 875 | # AllowTcpForwarding no 876 | # PermitTTY no 877 | # ForceCommand cvs server 878 | sshd_content 879 | 880 | # restart sshd service 881 | systemctl reload ssh 882 | systemctl reload sshd 883 | systemctl restart ssh 884 | systemctl restart sshd 885 | 886 | # Turn on automatic security updates. 887 | sudo dpkg-reconfigure -plow unattended-upgrades --unseen-only 888 | 889 | # set up a firewall with ufw. 890 | sudo apt-get install ufw 891 | sudo ufw default allow outgoing 892 | sudo ufw default deny incoming 893 | sudo ufw allow ${ssh_port}/tcp comment 'SSH' 894 | sudo ufw allow http comment 'HTTP' 895 | sudo ufw allow https comment 'HTTPS' 896 | yes | sudo ufw enable 897 | 898 | # Install Fail2Ban 899 | sudo apt-get install -y fail2ban 900 | rm /etc/fail2ban/jail.local 901 | touch /etc/fail2ban/jail.local 902 | 903 | # make fail2ban configuration 904 | cat <> /etc/fail2ban/jail.local 905 | # 906 | # WARNING: heavily refactored in 0.9.0 release. Please review and 907 | # customize settings for your setup. 908 | # 909 | # Changes: in most of the cases you should not modify this 910 | # file, but provide customizations in jail.local file, 911 | # or separate .conf files under jail.d/ directory, e.g.: 912 | # 913 | # HOW TO ACTIVATE JAILS: 914 | # 915 | # YOU SHOULD NOT MODIFY THIS FILE. 916 | # 917 | # It will probably be overwritten or improved in a distribution update. 918 | # 919 | # Provide customizations in a jail.local file or a jail.d/customisation.local. 920 | # For example to change the default bantime for all jails and to enable the 921 | # ssh-iptables jail the following (uncommented) would appear in the .local file. 922 | # See man 5 jail.conf for details. 923 | # 924 | # [DEFAULT] 925 | # bantime = 1h 926 | # 927 | # [sshd] 928 | # enabled = true 929 | # 930 | # See jail.conf(5) man page for more information 931 | 932 | 933 | 934 | # Comments: use '#' for comment lines and ';' (following a space) for inline comments 935 | 936 | 937 | [INCLUDES] 938 | 939 | #before = paths-distro.conf 940 | before = paths-debian.conf 941 | 942 | # The DEFAULT allows a global definition of the options. They can be overridden 943 | # in each jail afterwards. 944 | 945 | [DEFAULT] 946 | 947 | # 948 | # MISCELLANEOUS OPTIONS 949 | # 950 | 951 | # "bantime.increment" allows to use database for searching of previously banned ip's to increase a 952 | # default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32... 953 | #bantime.increment = true 954 | 955 | # "bantime.rndtime" is the max number of seconds using for mixing with random time 956 | # to prevent "clever" botnets calculate exact time IP can be unbanned again: 957 | #bantime.rndtime = 958 | 959 | # "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further) 960 | #bantime.maxtime = 961 | 962 | # "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier, 963 | # default value of factor is 1 and with default value of formula, the ban time 964 | # grows by 1, 2, 4, 8, 16 ... 965 | #bantime.factor = 1 966 | 967 | # "bantime.formula" used by default to calculate next value of ban time, default value below, 968 | # the same ban time growing will be reached by multipliers 1, 2, 4, 8, 16, 32... 969 | #bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor 970 | # 971 | # more aggressive example of formula has the same values only for factor "2.0 / 2.885385" : 972 | #bantime.formula = ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor) 973 | 974 | # "bantime.multipliers" used to calculate next value of ban time instead of formula, coresponding 975 | # previously ban count and given "bantime.factor" (for multipliers default is 1); 976 | # following example grows ban time by 1, 2, 4, 8, 16 ... and if last ban count greater as multipliers count, 977 | # always used last multiplier (64 in example), for factor '1' and original ban time 600 - 10.6 hours 978 | #bantime.multipliers = 1 2 4 8 16 32 64 979 | # following example can be used for small initial ban time (bantime=60) - it grows more aggressive at begin, 980 | # for bantime=60 the multipliers are minutes and equal: 1 min, 5 min, 30 min, 1 hour, 5 hour, 12 hour, 1 day, 2 day 981 | #bantime.multipliers = 1 5 30 60 300 720 1440 2880 982 | 983 | # "bantime.overalljails" (if true) specifies the search of IP in the database will be executed 984 | # cross over all jails, if false (dafault), only current jail of the ban IP will be searched 985 | #bantime.overalljails = false 986 | 987 | # -------------------- 988 | 989 | # "ignoreself" specifies whether the local resp. own IP addresses should be ignored 990 | # (default is true). Fail2ban will not ban a host which matches such addresses. 991 | #ignoreself = true 992 | 993 | # "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban 994 | # will not ban a host which matches an address in this list. Several addresses 995 | # can be defined using space (and/or comma) separator. 996 | #ignoreip = 127.0.0.1/8 ::1 997 | 998 | # External command that will take an tagged arguments to ignore, e.g. , 999 | # and return true if the IP is to be ignored. False otherwise. 1000 | # 1001 | # ignorecommand = /path/to/command 1002 | ignorecommand = 1003 | 1004 | # "bantime" is the number of seconds that a host is banned. 1005 | bantime = 10m 1006 | 1007 | # A host is banned if it has generated "maxretry" during the last "findtime" 1008 | # seconds. 1009 | findtime = 10m 1010 | 1011 | # "maxretry" is the number of failures before a host get banned. 1012 | maxretry = 5 1013 | 1014 | # "maxmatches" is the number of matches stored in ticket (resolvable via tag in actions). 1015 | maxmatches = %(maxretry)s 1016 | 1017 | # "backend" specifies the backend used to get files modification. 1018 | # Available options are "pyinotify", "gamin", "polling", "systemd" and "auto". 1019 | # This option can be overridden in each jail as well. 1020 | # 1021 | # pyinotify: requires pyinotify (a file alteration monitor) to be installed. 1022 | # If pyinotify is not installed, Fail2ban will use auto. 1023 | # gamin: requires Gamin (a file alteration monitor) to be installed. 1024 | # If Gamin is not installed, Fail2ban will use auto. 1025 | # polling: uses a polling algorithm which does not require external libraries. 1026 | # systemd: uses systemd python library to access the systemd journal. 1027 | # Specifying "logpath" is not valid for this backend. 1028 | # See "journalmatch" in the jails associated filter config 1029 | # auto: will try to use the following backends, in order: 1030 | # pyinotify, gamin, polling. 1031 | # 1032 | # Note: if systemd backend is chosen as the default but you enable a jail 1033 | # for which logs are present only in its own log files, specify some other 1034 | # backend for that jail (e.g. polling) and provide empty value for 1035 | # journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200 1036 | backend = auto 1037 | 1038 | # "usedns" specifies if jails should trust hostnames in logs, 1039 | # warn when DNS lookups are performed, or ignore all hostnames in logs 1040 | # 1041 | # yes: if a hostname is encountered, a DNS lookup will be performed. 1042 | # warn: if a hostname is encountered, a DNS lookup will be performed, 1043 | # but it will be logged as a warning. 1044 | # no: if a hostname is encountered, will not be used for banning, 1045 | # but it will be logged as info. 1046 | # raw: use raw value (no hostname), allow use it for no-host filters/actions (example user) 1047 | usedns = warn 1048 | 1049 | # "logencoding" specifies the encoding of the log files handled by the jail 1050 | # This is used to decode the lines from the log file. 1051 | # Typical examples: "ascii", "utf-8" 1052 | # 1053 | # auto: will use the system locale setting 1054 | logencoding = auto 1055 | 1056 | # "enabled" enables the jails. 1057 | # By default all jails are disabled, and it should stay this way. 1058 | # Enable only relevant to your setup jails in your .local or jail.d/*.conf 1059 | # 1060 | # true: jail will be enabled and log files will get monitored for changes 1061 | # false: jail is not enabled 1062 | enabled = false 1063 | 1064 | 1065 | # "mode" defines the mode of the filter (see corresponding filter implementation for more info). 1066 | mode = normal 1067 | 1068 | # "filter" defines the filter to use by the jail. 1069 | # By default jails have names matching their filter name 1070 | # 1071 | filter = %(__name__)s[mode=%(mode)s] 1072 | 1073 | 1074 | # 1075 | # ACTIONS 1076 | # 1077 | 1078 | # Some options used for actions 1079 | 1080 | # Destination email address used solely for the interpolations in 1081 | # jail.{conf,local,d/*} configuration files. 1082 | destemail = root@localhost 1083 | 1084 | # Sender email address used solely for some actions 1085 | sender = root@ 1086 | 1087 | # E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the 1088 | # mailing. Change mta configuration parameter to mail if you want to 1089 | # revert to conventional 'mail'. 1090 | mta = sendmail 1091 | 1092 | # Default protocol 1093 | protocol = tcp 1094 | 1095 | # Specify chain where jumps would need to be added in ban-actions expecting parameter chain 1096 | chain = 1097 | 1098 | # Ports to be banned 1099 | # Usually should be overridden in a particular jail 1100 | port = 0:65535 1101 | 1102 | # Format of user-agent https://tools.ietf.org/html/rfc7231#section-5.5.3 1103 | fail2ban_agent = Fail2Ban/%(fail2ban_version)s 1104 | 1105 | # 1106 | # Action shortcuts. To be used to define action parameter 1107 | 1108 | # Default banning action (e.g. iptables, iptables-new, 1109 | # iptables-multiport, shorewall, etc) It is used to define 1110 | # action_* variables. Can be overridden globally or per 1111 | # section within jail.local file 1112 | banaction = ufw 1113 | banaction_allports = ufw 1114 | 1115 | # The simplest action to take: ban only 1116 | action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] 1117 | 1118 | # ban & send an e-mail with whois report to the destemail. 1119 | action_mw = %(action_)s 1120 | %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] 1121 | 1122 | # ban & send an e-mail with whois report and relevant log lines 1123 | # to the destemail. 1124 | action_mwl = %(action_)s 1125 | %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"] 1126 | 1127 | # See the IMPORTANT note in action.d/xarf-login-attack for when to use this action 1128 | # 1129 | # ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines 1130 | # to the destemail. 1131 | action_xarf = %(action_)s 1132 | xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"] 1133 | 1134 | # ban IP on CloudFlare & send an e-mail with whois report and relevant log lines 1135 | # to the destemail. 1136 | action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"] 1137 | %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"] 1138 | 1139 | # Report block via blocklist.de fail2ban reporting service API 1140 | # 1141 | # See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action. 1142 | # Specify expected parameters in file action.d/blocklist_de.local or if the interpolation 1143 | # action_blocklist_de used for the action, set value of blocklist_de_apikey 1144 | # in your jail.local globally (section [DEFAULT]) or per specific jail section (resp. in 1145 | # corresponding jail.d/my-jail.local file). 1146 | # 1147 | action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"] 1148 | 1149 | # Report ban via badips.com, and use as blacklist 1150 | # 1151 | # See BadIPsAction docstring in config/action.d/badips.py for 1152 | # documentation for this action. 1153 | # 1154 | # NOTE: This action relies on banaction being present on start and therefore 1155 | # should be last action defined for a jail. 1156 | # 1157 | action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"] 1158 | # 1159 | # Report ban via badips.com (uses action.d/badips.conf for reporting only) 1160 | # 1161 | action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"] 1162 | 1163 | # Report ban via abuseipdb.com. 1164 | # 1165 | # See action.d/abuseipdb.conf for usage example and details. 1166 | # 1167 | action_abuseipdb = abuseipdb 1168 | 1169 | # Choose default action. To change, just override value of 'action' with the 1170 | # interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local 1171 | # globally (section [DEFAULT]) or per specific section 1172 | action = %(action_)s 1173 | 1174 | 1175 | # 1176 | # JAILS 1177 | # 1178 | 1179 | # 1180 | # SSH servers 1181 | # 1182 | 1183 | [sshd] 1184 | 1185 | # To use more aggressive sshd modes set filter parameter "mode" in jail.local: 1186 | # normal (default), ddos, extra or aggressive (combines all). 1187 | # See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details. 1188 | #mode = normal 1189 | port = ssh 1190 | logpath = %(sshd_log)s 1191 | backend = %(sshd_backend)s 1192 | 1193 | 1194 | [dropbear] 1195 | 1196 | port = ssh 1197 | logpath = %(dropbear_log)s 1198 | backend = %(dropbear_backend)s 1199 | 1200 | 1201 | [selinux-ssh] 1202 | 1203 | port = ssh 1204 | logpath = %(auditd_log)s 1205 | 1206 | 1207 | # 1208 | # HTTP servers 1209 | # 1210 | 1211 | [apache-auth] 1212 | 1213 | port = http,https 1214 | logpath = %(apache_error_log)s 1215 | 1216 | 1217 | [apache-badbots] 1218 | # Ban hosts which agent identifies spammer robots crawling the web 1219 | # for email addresses. The mail outputs are buffered. 1220 | port = http,https 1221 | logpath = %(apache_access_log)s 1222 | bantime = 48h 1223 | maxretry = 1 1224 | 1225 | 1226 | [apache-noscript] 1227 | 1228 | port = http,https 1229 | logpath = %(apache_error_log)s 1230 | 1231 | 1232 | [apache-overflows] 1233 | 1234 | port = http,https 1235 | logpath = %(apache_error_log)s 1236 | maxretry = 2 1237 | 1238 | 1239 | [apache-nohome] 1240 | 1241 | port = http,https 1242 | logpath = %(apache_error_log)s 1243 | maxretry = 2 1244 | 1245 | 1246 | [apache-botsearch] 1247 | 1248 | port = http,https 1249 | logpath = %(apache_error_log)s 1250 | maxretry = 2 1251 | 1252 | 1253 | [apache-fakegooglebot] 1254 | 1255 | port = http,https 1256 | logpath = %(apache_access_log)s 1257 | maxretry = 1 1258 | ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot 1259 | 1260 | 1261 | [apache-modsecurity] 1262 | 1263 | port = http,https 1264 | logpath = %(apache_error_log)s 1265 | maxretry = 2 1266 | 1267 | 1268 | [apache-shellshock] 1269 | 1270 | port = http,https 1271 | logpath = %(apache_error_log)s 1272 | maxretry = 1 1273 | 1274 | 1275 | [openhab-auth] 1276 | 1277 | filter = openhab 1278 | banaction = %(banaction_allports)s 1279 | logpath = /opt/openhab/logs/request.log 1280 | 1281 | 1282 | [nginx-http-auth] 1283 | 1284 | port = http,https 1285 | logpath = %(nginx_error_log)s 1286 | 1287 | # To use 'nginx-limit-req' jail you should have ngx_http_limit_req_module 1288 | # and define limit_req and limit_req_zone as described in nginx documentation 1289 | # http://nginx.org/en/docs/http/ngx_http_limit_req_module.html 1290 | # or for example see in 'config/filter.d/nginx-limit-req.conf' 1291 | [nginx-limit-req] 1292 | port = http,https 1293 | logpath = %(nginx_error_log)s 1294 | 1295 | [nginx-botsearch] 1296 | 1297 | port = http,https 1298 | logpath = %(nginx_error_log)s 1299 | maxretry = 2 1300 | 1301 | 1302 | # Ban attackers that try to use PHP's URL-fopen() functionality 1303 | # through GET/POST variables. - Experimental, with more than a year 1304 | # of usage in production environments. 1305 | 1306 | [php-url-fopen] 1307 | 1308 | port = http,https 1309 | logpath = %(nginx_access_log)s 1310 | %(apache_access_log)s 1311 | 1312 | 1313 | [suhosin] 1314 | 1315 | port = http,https 1316 | logpath = %(suhosin_log)s 1317 | 1318 | 1319 | [lighttpd-auth] 1320 | # Same as above for Apache's mod_auth 1321 | # It catches wrong authentifications 1322 | port = http,https 1323 | logpath = %(lighttpd_error_log)s 1324 | 1325 | 1326 | # 1327 | # Webmail and groupware servers 1328 | # 1329 | 1330 | [roundcube-auth] 1331 | 1332 | port = http,https 1333 | logpath = %(roundcube_errors_log)s 1334 | # Use following line in your jail.local if roundcube logs to journal. 1335 | #backend = %(syslog_backend)s 1336 | 1337 | 1338 | [openwebmail] 1339 | 1340 | port = http,https 1341 | logpath = /var/log/openwebmail.log 1342 | 1343 | 1344 | [horde] 1345 | 1346 | port = http,https 1347 | logpath = /var/log/horde/horde.log 1348 | 1349 | 1350 | [groupoffice] 1351 | 1352 | port = http,https 1353 | logpath = /home/groupoffice/log/info.log 1354 | 1355 | 1356 | [sogo-auth] 1357 | # Monitor SOGo groupware server 1358 | # without proxy this would be: 1359 | # port = 20000 1360 | port = http,https 1361 | logpath = /var/log/sogo/sogo.log 1362 | 1363 | 1364 | [tine20] 1365 | 1366 | logpath = /var/log/tine20/tine20.log 1367 | port = http,https 1368 | 1369 | 1370 | # 1371 | # Web Applications 1372 | # 1373 | # 1374 | 1375 | [drupal-auth] 1376 | 1377 | port = http,https 1378 | logpath = %(syslog_daemon)s 1379 | backend = %(syslog_backend)s 1380 | 1381 | [guacamole] 1382 | 1383 | port = http,https 1384 | logpath = /var/log/tomcat*/catalina.out 1385 | #logpath = /var/log/guacamole.log 1386 | 1387 | [monit] 1388 | #Ban clients brute-forcing the monit gui login 1389 | port = 2812 1390 | logpath = /var/log/monit 1391 | /var/log/monit.log 1392 | 1393 | 1394 | [webmin-auth] 1395 | 1396 | port = 10000 1397 | logpath = %(syslog_authpriv)s 1398 | backend = %(syslog_backend)s 1399 | 1400 | 1401 | [froxlor-auth] 1402 | 1403 | port = http,https 1404 | logpath = %(syslog_authpriv)s 1405 | backend = %(syslog_backend)s 1406 | 1407 | 1408 | # 1409 | # HTTP Proxy servers 1410 | # 1411 | # 1412 | 1413 | [squid] 1414 | 1415 | port = 80,443,3128,8080 1416 | logpath = /var/log/squid/access.log 1417 | 1418 | 1419 | [3proxy] 1420 | 1421 | port = 3128 1422 | logpath = /var/log/3proxy.log 1423 | 1424 | 1425 | # 1426 | # FTP servers 1427 | # 1428 | 1429 | 1430 | [proftpd] 1431 | 1432 | port = ftp,ftp-data,ftps,ftps-data 1433 | logpath = %(proftpd_log)s 1434 | backend = %(proftpd_backend)s 1435 | 1436 | 1437 | [pure-ftpd] 1438 | 1439 | port = ftp,ftp-data,ftps,ftps-data 1440 | logpath = %(pureftpd_log)s 1441 | backend = %(pureftpd_backend)s 1442 | 1443 | 1444 | [gssftpd] 1445 | 1446 | port = ftp,ftp-data,ftps,ftps-data 1447 | logpath = %(syslog_daemon)s 1448 | backend = %(syslog_backend)s 1449 | 1450 | 1451 | [wuftpd] 1452 | 1453 | port = ftp,ftp-data,ftps,ftps-data 1454 | logpath = %(wuftpd_log)s 1455 | backend = %(wuftpd_backend)s 1456 | 1457 | 1458 | [vsftpd] 1459 | # or overwrite it in jails.local to be 1460 | # logpath = %(syslog_authpriv)s 1461 | # if you want to rely on PAM failed login attempts 1462 | # vsftpd's failregex should match both of those formats 1463 | port = ftp,ftp-data,ftps,ftps-data 1464 | logpath = %(vsftpd_log)s 1465 | 1466 | 1467 | # 1468 | # Mail servers 1469 | # 1470 | 1471 | # ASSP SMTP Proxy Jail 1472 | [assp] 1473 | 1474 | port = smtp,465,submission 1475 | logpath = /root/path/to/assp/logs/maillog.txt 1476 | 1477 | 1478 | [courier-smtp] 1479 | 1480 | port = smtp,465,submission 1481 | logpath = %(syslog_mail)s 1482 | backend = %(syslog_backend)s 1483 | 1484 | 1485 | [postfix] 1486 | # To use another modes set filter parameter "mode" in jail.local: 1487 | mode = more 1488 | port = smtp,465,submission 1489 | logpath = %(postfix_log)s 1490 | backend = %(postfix_backend)s 1491 | 1492 | 1493 | [postfix-rbl] 1494 | 1495 | filter = postfix[mode=rbl] 1496 | port = smtp,465,submission 1497 | logpath = %(postfix_log)s 1498 | backend = %(postfix_backend)s 1499 | maxretry = 1 1500 | 1501 | 1502 | [sendmail-auth] 1503 | 1504 | port = submission,465,smtp 1505 | logpath = %(syslog_mail)s 1506 | backend = %(syslog_backend)s 1507 | 1508 | 1509 | [sendmail-reject] 1510 | # To use more aggressive modes set filter parameter "mode" in jail.local: 1511 | # normal (default), extra or aggressive 1512 | # See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details. 1513 | #mode = normal 1514 | port = smtp,465,submission 1515 | logpath = %(syslog_mail)s 1516 | backend = %(syslog_backend)s 1517 | 1518 | 1519 | [qmail-rbl] 1520 | 1521 | filter = qmail 1522 | port = smtp,465,submission 1523 | logpath = /service/qmail/log/main/current 1524 | 1525 | 1526 | # dovecot defaults to logging to the mail syslog facility 1527 | # but can be set by syslog_facility in the dovecot configuration. 1528 | [dovecot] 1529 | 1530 | port = pop3,pop3s,imap,imaps,submission,465,sieve 1531 | logpath = %(dovecot_log)s 1532 | backend = %(dovecot_backend)s 1533 | 1534 | 1535 | [sieve] 1536 | 1537 | port = smtp,465,submission 1538 | logpath = %(dovecot_log)s 1539 | backend = %(dovecot_backend)s 1540 | 1541 | 1542 | [solid-pop3d] 1543 | 1544 | port = pop3,pop3s 1545 | logpath = %(solidpop3d_log)s 1546 | 1547 | 1548 | [exim] 1549 | # see filter.d/exim.conf for further modes supported from filter: 1550 | #mode = normal 1551 | port = smtp,465,submission 1552 | logpath = %(exim_main_log)s 1553 | 1554 | 1555 | [exim-spam] 1556 | 1557 | port = smtp,465,submission 1558 | logpath = %(exim_main_log)s 1559 | 1560 | 1561 | [kerio] 1562 | 1563 | port = imap,smtp,imaps,465 1564 | logpath = /opt/kerio/mailserver/store/logs/security.log 1565 | 1566 | 1567 | # 1568 | # Mail servers authenticators: might be used for smtp,ftp,imap servers, so 1569 | # all relevant ports get banned 1570 | # 1571 | 1572 | [courier-auth] 1573 | 1574 | port = smtp,465,submission,imap,imaps,pop3,pop3s 1575 | logpath = %(syslog_mail)s 1576 | backend = %(syslog_backend)s 1577 | 1578 | 1579 | [postfix-sasl] 1580 | 1581 | filter = postfix[mode=auth] 1582 | port = smtp,465,submission,imap,imaps,pop3,pop3s 1583 | # You might consider monitoring /var/log/mail.warn instead if you are 1584 | # running postfix since it would provide the same log lines at the 1585 | # "warn" level but overall at the smaller filesize. 1586 | logpath = %(postfix_log)s 1587 | backend = %(postfix_backend)s 1588 | 1589 | 1590 | [perdition] 1591 | 1592 | port = imap,imaps,pop3,pop3s 1593 | logpath = %(syslog_mail)s 1594 | backend = %(syslog_backend)s 1595 | 1596 | 1597 | [squirrelmail] 1598 | 1599 | port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks 1600 | logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log 1601 | 1602 | 1603 | [cyrus-imap] 1604 | 1605 | port = imap,imaps 1606 | logpath = %(syslog_mail)s 1607 | backend = %(syslog_backend)s 1608 | 1609 | 1610 | [uwimap-auth] 1611 | 1612 | port = imap,imaps 1613 | logpath = %(syslog_mail)s 1614 | backend = %(syslog_backend)s 1615 | 1616 | 1617 | # 1618 | # 1619 | # DNS servers 1620 | # 1621 | 1622 | 1623 | # !!! WARNING !!! 1624 | # Since UDP is connection-less protocol, spoofing of IP and imitation 1625 | # of illegal actions is way too simple. Thus enabling of this filter 1626 | # might provide an easy way for implementing a DoS against a chosen 1627 | # victim. See 1628 | # http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html 1629 | # Please DO NOT USE this jail unless you know what you are doing. 1630 | # 1631 | # IMPORTANT: see filter.d/named-refused for instructions to enable logging 1632 | # This jail blocks UDP traffic for DNS requests. 1633 | # [named-refused-udp] 1634 | # 1635 | # filter = named-refused 1636 | # port = domain,953 1637 | # protocol = udp 1638 | # logpath = /var/log/named/security.log 1639 | 1640 | # IMPORTANT: see filter.d/named-refused for instructions to enable logging 1641 | # This jail blocks TCP traffic for DNS requests. 1642 | 1643 | [named-refused] 1644 | 1645 | port = domain,953 1646 | logpath = /var/log/named/security.log 1647 | 1648 | 1649 | [nsd] 1650 | 1651 | port = 53 1652 | action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"] 1653 | %(default/action_)s[name=%(__name__)s-udp, protocol="udp"] 1654 | logpath = /var/log/nsd.log 1655 | 1656 | 1657 | # 1658 | # Miscellaneous 1659 | # 1660 | 1661 | [asterisk] 1662 | 1663 | port = 5060,5061 1664 | action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"] 1665 | %(default/action_)s[name=%(__name__)s-udp, protocol="udp"] 1666 | logpath = /var/log/asterisk/messages 1667 | maxretry = 10 1668 | 1669 | 1670 | [freeswitch] 1671 | 1672 | port = 5060,5061 1673 | action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"] 1674 | %(default/action_)s[name=%(__name__)s-udp, protocol="udp"] 1675 | logpath = /var/log/freeswitch.log 1676 | maxretry = 10 1677 | 1678 | 1679 | # enable adminlog; it will log to a file inside znc's directory by default. 1680 | [znc-adminlog] 1681 | 1682 | port = 6667 1683 | logpath = /var/lib/znc/moddata/adminlog/znc.log 1684 | 1685 | 1686 | # To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or 1687 | # equivalent section: 1688 | # log-warnings = 2 1689 | # 1690 | # for syslog (daemon facility) 1691 | # [mysqld_safe] 1692 | # syslog 1693 | # 1694 | # for own logfile 1695 | # [mysqld] 1696 | # log-error=/var/log/mysqld.log 1697 | [mysqld-auth] 1698 | 1699 | port = 3306 1700 | logpath = %(mysql_log)s 1701 | backend = %(mysql_backend)s 1702 | 1703 | 1704 | # Log wrong MongoDB auth (for details see filter 'filter.d/mongodb-auth.conf') 1705 | [mongodb-auth] 1706 | # change port when running with "--shardsvr" or "--configsvr" runtime operation 1707 | port = 27017 1708 | logpath = /var/log/mongodb/mongodb.log 1709 | 1710 | 1711 | # Jail for more extended banning of persistent abusers 1712 | # !!! WARNINGS !!! 1713 | # 1. Make sure that your loglevel specified in fail2ban.conf/.local 1714 | # is not at DEBUG level -- which might then cause fail2ban to fall into 1715 | # an infinite loop constantly feeding itself with non-informative lines 1716 | # 2. Increase dbpurgeage defined in fail2ban.conf to e.g. 648000 (7.5 days) 1717 | # to maintain entries for failed logins for sufficient amount of time 1718 | [recidive] 1719 | 1720 | logpath = /var/log/fail2ban.log 1721 | banaction = %(banaction_allports)s 1722 | bantime = 1w 1723 | findtime = 1d 1724 | 1725 | 1726 | # Generic filter for PAM. Has to be used with action which bans all 1727 | # ports such as iptables-allports, shorewall 1728 | 1729 | [pam-generic] 1730 | # pam-generic filter can be customized to monitor specific subset of 'tty's 1731 | banaction = %(banaction_allports)s 1732 | logpath = %(syslog_authpriv)s 1733 | backend = %(syslog_backend)s 1734 | 1735 | 1736 | [xinetd-fail] 1737 | 1738 | banaction = iptables-multiport-log 1739 | logpath = %(syslog_daemon)s 1740 | backend = %(syslog_backend)s 1741 | maxretry = 2 1742 | 1743 | 1744 | # stunnel - need to set port for this 1745 | [stunnel] 1746 | 1747 | logpath = /var/log/stunnel4/stunnel.log 1748 | 1749 | 1750 | [ejabberd-auth] 1751 | 1752 | port = 5222 1753 | logpath = /var/log/ejabberd/ejabberd.log 1754 | 1755 | 1756 | [counter-strike] 1757 | 1758 | logpath = /opt/cstrike/logs/L[0-9]*.log 1759 | tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039 1760 | udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015 1761 | action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"] 1762 | %(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"] 1763 | 1764 | [softethervpn] 1765 | port = 500,4500 1766 | protocol = udp 1767 | logpath = /usr/local/vpnserver/security_log/*/sec.log 1768 | 1769 | [gitlab] 1770 | port = http,https 1771 | logpath = /var/log/gitlab/gitlab-rails/application.log 1772 | 1773 | [grafana] 1774 | port = http,https 1775 | logpath = /var/log/grafana/grafana.log 1776 | 1777 | [bitwarden] 1778 | port = http,https 1779 | logpath = /home/*/bwdata/logs/identity/Identity/log.txt 1780 | 1781 | [centreon] 1782 | port = http,https 1783 | logpath = /var/log/centreon/login.log 1784 | 1785 | # consider low maxretry and a long bantime 1786 | # nobody except your own Nagios server should ever probe nrpe 1787 | [nagios] 1788 | 1789 | logpath = %(syslog_daemon)s ; nrpe.cfg may define a different log_facility 1790 | backend = %(syslog_backend)s 1791 | maxretry = 1 1792 | 1793 | 1794 | [oracleims] 1795 | # see "oracleims" filter file for configuration requirement for Oracle IMS v6 and above 1796 | logpath = /opt/sun/comms/messaging64/log/mail.log_current 1797 | banaction = %(banaction_allports)s 1798 | 1799 | [directadmin] 1800 | logpath = /var/log/directadmin/login.log 1801 | port = 2222 1802 | 1803 | [portsentry] 1804 | logpath = /var/lib/portsentry/portsentry.history 1805 | maxretry = 1 1806 | 1807 | [pass2allow-ftp] 1808 | # this pass2allow example allows FTP traffic after successful HTTP authentication 1809 | port = ftp,ftp-data,ftps,ftps-data 1810 | # knocking_url variable must be overridden to some secret value in jail.local 1811 | knocking_url = /knocking/ 1812 | filter = apache-pass[knocking_url="%(knocking_url)s"] 1813 | # access log of the website with HTTP auth 1814 | logpath = %(apache_access_log)s 1815 | blocktype = RETURN 1816 | returntype = DROP 1817 | action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s, 1818 | actionstart_on_demand=false, actionrepair_on_unban=true] 1819 | bantime = 1h 1820 | maxretry = 1 1821 | findtime = 1 1822 | 1823 | 1824 | [murmur] 1825 | # AKA mumble-server 1826 | port = 64738 1827 | action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"] 1828 | %(default/action_)s[name=%(__name__)s-udp, protocol="udp"] 1829 | logpath = /var/log/mumble-server/mumble-server.log 1830 | 1831 | 1832 | [screensharingd] 1833 | # For Mac OS Screen Sharing Service (VNC) 1834 | logpath = /var/log/system.log 1835 | logencoding = utf-8 1836 | 1837 | [haproxy-http-auth] 1838 | # HAProxy by default doesn't log to file you'll need to set it up to forward 1839 | # logs to a syslog server which would then write them to disk. 1840 | # See "haproxy-http-auth" filter for a brief cautionary note when setting 1841 | # maxretry and findtime. 1842 | logpath = /var/log/haproxy.log 1843 | 1844 | [slapd] 1845 | port = ldap,ldaps 1846 | logpath = /var/log/slapd.log 1847 | 1848 | [domino-smtp] 1849 | port = smtp,ssmtp 1850 | logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log 1851 | 1852 | [phpmyadmin-syslog] 1853 | port = http,https 1854 | logpath = %(syslog_authpriv)s 1855 | backend = %(syslog_backend)s 1856 | 1857 | 1858 | [zoneminder] 1859 | # Zoneminder HTTP/HTTPS web interface auth 1860 | # Logs auth failures to apache2 error log 1861 | port = http,https 1862 | logpath = %(apache_error_log)s 1863 | 1864 | [traefik-auth] 1865 | # to use 'traefik-auth' filter you have to configure your Traefik instance, 1866 | # see filter.d/traefik-auth.conf for details and service example. 1867 | port = http,https 1868 | logpath = /var/log/traefik/access.log 1869 | 1870 | [scanlogd] 1871 | logpath = %(syslog_local0)s 1872 | banaction = %(banaction_allports)s 1873 | fail2ban_ban 1874 | 1875 | 1876 | # Restart the fail2ban service. 1877 | sudo systemctl restart fail2ban 1878 | echo "Congratulations your setup is done" 1879 | echo "Admin email: ${admin_email} and password: ${admin_password}" 1880 | echo "Database user: ${db_user} , password: ${db_password} and name ${db_name}" 1881 | echo "Elasticsearch user name: ${es_user} and password: ${es_password}" 1882 | echo "The Mastodon instance can be accessed on https://${domain_name}" 1883 | echo "Now SSH port is ${ssh_port}" --------------------------------------------------------------------------------