L2DC Linux Server Guide
L2DC Linux Server Guide
BASIC SETUP
Update Installed System Automatic Update Routine Server Timezone Linux Kernel Optional - Setup DynDNS
Updating System
When loggin in, update your system: root@l2dcserver:~# aptitude update root@l2dcserver:~# aptitude safe-upgrade -y
Setting TimeZone?
As international admins, you may live in Brazil and set up a Server in Germany. Its very important to setup your timezone correctly to avoid misunderstandings and among your users. When you decide what timezone you will use, set it up now: root@l2dcserver:~# dpkg-reconfigure tzdata And follow screen instructions.
1 de 11
28-03-2010 20:39
SSH Server
OpenSSH is a FREE version of the SSH connectivity tools that technical users of the Internet rely on. Users of telnet, rlogin, and ftp may not realize that their password is transmitted across the Internet unencrypted, but it is. OpenSSH encrypts all traffic (including passwords) to effectively eliminate eavesdropping, connection hijacking, and other attacks. Additionally, OpenSSH provides secure tunneling capabilities and several authentication methods, and supports all SSH protocol versions. An well configured SSH Server will make your Server almost unhackeable. This is why you should give special attention to this topic. Lets start installing SSH Server. root@l2dcserver:~# aptitude install openssh-server To correctly configure SSH Server, add of modify this lines on /etc/ssh/sshd_config: Protocol 2 PermitRootLogin no IgnoreRhosts yes HostbasedAuthentication no PermitEmptyPasswords no # Subsystem sftp /usr/lib/openssh/sftp-server AllowUsers user SSH1 protocol have some known issues, this is why we set protocol 2 only here. We will not allow root login via SSH or empty passwords anymore. This is a huge security problem. Host-based auth and rhosts will not be considered by SSH Server anymore. Following "Production Server" idea, i will disable sftp not required service. Now, lets test SSH login with username user on l2dcserver: cyberfox@firefox:~$ ssh 192.168.0.70 -l user The authenticity of host '192.168.0.70 (192.168.0.70)' can't be established. RSA key fingerprint is 3e:06:b0:63:b3:ae:f3:d4:53:03:81:d3:ec:af:1c:ed. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.0.70' (RSA) to the list of known hosts. user@192.168.0.70's password: Linux l2dcserver 2.6.31-19-server #56-Ubuntu SMP Thu Jan 28 03:40:48 UTC 2010 x86_64 Last login: Mon Mar 1 07:41:06 2010 user@l2dcserver:~$ sudo su [sudo] password for user: root@l2dcserver:~# SSH Server is now set up and ready for use.
2 de 11
28-03-2010 20:39
cyberfox@firefox:~$ ssh-copy-id -i /home/cyberfox/.ssh/id_rsa.pub user@192.168.0.70 user@192.168.0.70's password: Now try logging into the machine, with "ssh 'user@192.168.0.70'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting. Local setup is done, lets login on Server using key auth and finish settings. When you try login to your Server, SSH will ask for your KEY password. Enter it and log in normally. cyberfox@firefox:~$ ssh 192.168.0.70 -l user Now everything is working fine, we need to disable password authentication on Server. Add or change following lines on /etc/ssh/sshd_config: PasswordAuthentication no UsePAM no Now, restart SSH Server to ensure all settings take place: root@l2dcserver:~# service ssh restart NOTE: Your public and private key are kept in hidden /home/youruser/.ssh/ directory. Save it on a secret, safe place. Without your private key, you will not be able to login on your Server. Recommended reading: https://help.ubuntu.com/9.10/serverguide/C/openssh-server.html
Optional - OSSEC-HIDS
I like and use this one. Developed by a brazillian guy, OSSEC is a scalable, multi-platform, open source Host-based Intrusion Detection System (HIDS). It has a powerful correlation and analysis engine, integrating log analysis, file integrity checking, centralized policy enforcement, rootkit detection, real-time alerting and active response. This toll will make attackers life a lot harder and will protect your system against almost all known problems. This worth a try. OSSEC can be found here: http://www.ossec.net/main/downloads/ Download it using wget: root@l2dcserver:~# wget http://www.ossec.net/files/ossec-hids-2.3.tar.gz Unpack it and enter on created directory: root@l2dcserver:~# tar -xzf ossec-hids-2.3.tar.gz root@l2dcserver:~# cd ossec-hids-2.3 Now, you will need compile tools in order to build ossec via given script. To install those tools, run: root@l2dcserver:~/ossec-hids-2.3# aptitude install build-essential When done, install it using: root@l2dcserver:~/ossec-hids-2.3# ./install.sh Choose your preferred language, local setup, set your email adress and leave all default until the end of installation. Its not adviced leave compilers installed on a Production Server: root@l2dcserver:~/ossec-hids-2.3# aptitude remove build-essential Crowded servers are being overrunned by OSSEC emails, you can raise email alerts threshold from 7 to 11, for example. This will disable a lot of false-positives. Personally, I keep 7 for paranoid purposes. Edit /var/ossec/etc/ossec.conf and change this value from 7 to 11 to reduce ossec email alerts. <alerts> <log_alert_level>1</log_alert_level> <email_alert_level>7</email_alert_level> </alerts> To completely disable it, change yes to no here. - Not Recommended <email_notification>yes</email_notification> Believe me, you will not leave this enabled for now. When Active Response is enable and OSSEC is running, it will block any hack attempt IP for 20 minutes. Have this in mind! This means if you try to change your accesslevel on MySQL using PHPMyAdmin, for example, OSSEC will detect a successful hack attempt and you lock your access for 20 minutes. There is nothing you can do, except wait, login again and temporarily disable it. In the end, OSSEC helps me more tham annoy me. I like this tool. root@l2dcserver:~/ossec-hids-2.3# service ossec stop
Optional - PSAD
This tool was designed to block DDoS attacks with a Server-side approach. It wrks in a similar way from OSSEC, blacklisting temporarily highly traffic strange packets. On my Server, default config options is ok so far and it consume very few resources. Its a good call. Install it using: root@l2dcserver:~# aptitude install psad mailutils And now you are protected. Recommended reading: http://www.nsa.gov/ia/guidance/security_configuration_guides/operating_systems.shtml
3 de 11
28-03-2010 20:39
MySQL Server
MySQL is the world's most popular open source database software, with over 100 million copies of its software downloaded or distributed throughout it's history. With its superior speed, reliability, and ease of use, MySQL has become the preferred choice for Web, Web 2.0, SaaS, ISV, Telecom companies and forward-thinking corporate IT Managers because it eliminates the major problems associated with downtime, maintenance and administration for modern, online applications. So far, this is the choice for all L2DC Based Servers admins. At this point, we will not aim for any specific configurations, like tweaking memory usage, setting a separate HD for database, response time and changing sql engine. This will be a basic and secure setup for start. Install it by running: root@l2dcserver:~# aptitude install mysql-server You need increase max_connections on /etc/mysql/my.cnf to avoid MySQL locks for multiple connections. max_connections = 300 Now run MySQL security script: root@l2dcserver:~# mysql_secure_installation This will remove test table and user, reset privileges and put your MySQL in production state. Once installed, MySQL will be automatically installed using default settings. And you will be able to login on its console and creating a database l2dc and grant all privileges on l2dc user to that database. NOTE: As a basic setup, this fits well. On advanced installs, we can use separated databases for loginserver, gameservers and communityservers. Log in on MySQL console and enter this settings: root@l2dcserver:~# mysql -u root -p mysql> CREATE USER 'l2dc'@'localhost' IDENTIFIED BY 'YOURPASSWORD'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT USAGE ON * . * TO 'l2dc'@'localhost' IDENTIFIED BY 'YOURPASSWORD' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; Query OK, 0 rows affected (0.00 sec) mysql> CREATE DATABASE IF NOT EXISTS `l2dc` ; Query OK, 1 row affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON `l2dc` . * TO 'l2dc'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> quit; Bye NOTE: Pay attention on YOURPASSWORD on lines 1 and 2. That will the chosen password for l2dc user. Restart MySQL: root@l2dcserver:~# service mysql restart Recommended reading: https://help.ubuntu.com/9.10/serverguide/C/mysql.html
4 de 11
28-03-2010 20:39
MyISAM
MyISAM is the default storage engine for the MySQL relational database management system. It is based on the older ISAM code but has many useful extensions. The major deficiency of MyISAM is the absence of transactions support. Therefore in recent MySQL versions, the InnoDB engine has widely started to replace MyISAM to allow additional referential integrity constraints, and higher concurrency. Each MyISAM table is stored on disk in three files. The files have names that begin with the table name and have an extension to indicate the file type. MySQL uses a .frm file to store the definition of the table, but this file is not a part of the MyISAM engine, but instead is a part of the server. The data file has a .MYD (MYData) extension. The index file has a .MYI (MYIndex) extension. Lets start by getting pre configured files and editing them. root@l2dcserver:~# cp -a /usr/share/doc/mysql-server-5.1/examples/my-large.cnf.gz /etc/mysql/ root@l2dcserver:~# gzip -d /etc/mysql/my-large.cnf.gz Now, edit the file /etc/mysql/my-large.cnf and add or correct the following lines on [mysqld] section: [mysqld] skip-locking skip-innodb key_buffer = 120M max_allowed_packet = 8M table_cache = 60000 sort_buffer_size = 2M read_buffer_size = 2M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 30M thread_cache_size = 128 query_cache_size = 256M query_cache_limit = 512M # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 max_connections = 200 tmp_table_size = 270M max_heap_table_size = 270M memlock If you set a spare disk for MySQL installation now its time to configure it. Assuming your spare disk was mounted as /database (you can ask for this on Server initial setup), enter proper datadir setting on your [mysqld] section: datadir = /database/mysql When everything is correctly done, backup your original my.cnf and let our settings take place: root@l2dcserver:~# mv /etc/mysql/my.cnf /etc/mysql/my.cnf.backup root@l2dcserver:~# mv /etc/mysql/my-large.cnf /etc/mysql/my.cnf A MySQL Server restart will take care of new settings: root@l2dcserver:~# service mysql restart Remember fine tunning your MySQL Server running mysqltuner script every two days.
InnoDB
InnoDB is a storage engine for MySQL, included as standard in all current binaries distributed by MySQL AB. Its main enhancement over other storage engines available for use with MySQL is ACID-compliant transaction support [ACID (atomicity, consistency, isolation, durability) is a set of properties that guarantee that database transactions are processed reliably. The concept of ACID is to evaluate databases and application architecture. In the context of databases, a single logical operation on the data is called a transaction. For example, a transfer of funds from one bank account to another, even though that might involve multiple changes (such as debiting one account and crediting another)], similar to PostgreSQL, along with foreign key support (Declarative Referential Integrity). InnoDB became a product of Oracle Corporation after their acquisition of Innobase Oy in October 2005. The software is dual licensed; it is distributed under the GNU General Public License, but can also be licensed to parties wishing to combine InnoDB in proprietary software. Please note InnoDB consumes a lot more RAMtham MyISAM. This setup is based on a dedicated 4GB for MySQL. Lets start by getting pre configured files and editing them. root@l2dcserver:~# cp -a /usr/share/doc/mysql-server-5.1/examples/my-innodb-heavy-4G.cnf.gz /etc/mysql/ root@l2dcserver:~# gzip -d /etc/mysql/my-innodb-heavy-4G.cnf.gz Now, edit the file /etc/mysql/my-innodb-heavy-4G.cnf and add or correct the following lines: [mysqld] max_connections = 200 max_connect_errors = 200 memlock max_heap_table_size = 2G sort_buffer_size = 4M join_buffer_size = 8M default_table_type = INNODB transaction_isolation = REPEATABLE-READ tmp_table_size = 2G key_buffer_size = 32M read_buffer_size = 1M read_rnd_buffer_size = 4M bulk_insert_buffer_size = 1M myisam_sort_buffer_size = 1M myisam_max_extra_sort_file_size = 10G myisam_repair_threads = 1 innodb_additional_mem_pool_size = 8M innodb_buffer_pool_size = 500M innodb_data_file_path = ibdata1:10M:autoextend innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 8M innodb_log_file_size = 256M innodb_file_per_table innodb_support_xa=0 MemLock?: Try to keep all data in memory, avoiding HD use. InnoDB_Buffer_Pool_Size: This is the total size of all your InnoDB tables. Keep an eye on it and increase it when reaching the limit. Innodb_Log_File_Size: Careful changing this on a Production Environment. If you do this, your Server will not start again if you dont delete the logfiles. Dirty, but works. Default location is /var/lib/mysql/ root@l2dcserver:~# rm -rf /var/lib/mysql/ib_logfile* If you set a spare disk for MySQL installation now its time to configure it. Assuming your spare disk was mounted as /database (you can ask for this on Server initial setup), enter proper datadir setting on your [mysqld] section: datadir = /database/mysql When everything is correctly done, backup your original my.cnf and let our settings take place: root@l2dcserver:~# mv /etc/mysql/my.cnf /etc/mysql/my.cnf.backup root@l2dcserver:~# mv /etc/mysql/my-innodb-heavy-4G.cnf /etc/mysql/my.cnf A MySQL Server restart will take care of new settings: root@l2dcserver:~# service mysql restart
InnoDB is not the default database engine from L2DC SQL files. To make our life easier, I will share a script which automate the process of changing default database engine on project SQL files. Create the file dbchange.sh, set it as executable and paste this script on it. #!/bin/bash # Changing database engine from L2DC default MyISAM to InnoDB. find /home/l2dc/Server/sql -maxdepth 1 -name '*.sql' | xargs perl -i.bkp -p -e 's/MyISAM/InnoDB/ig;' rm -rf /home/l2dc/Server/sql/*.bkp echo Done Run it before install/update your database with database_installer.sh
Optional - MySQLTuner
MySQLTuner is a script written in Perl that will assist you with your MySQL configuration and make recommendations for increased performance and stability. Within seconds, it will display statistics about your MySQL installation and the areas where it can be improved. Its a good idea run it every two days on fresh installations to keep tweaking MySQL settings on Server restart/updates. Download it using: wget mysqltuner.pl
5 de 11
28-03-2010 20:39
6 de 11
28-03-2010 20:39
Subversion
In software development, Subversion (SVN) is a version-control system initiated in 2000 by CollabNet? Inc. Developers use Subversion to maintain current and historical versions of files such as source code, web pages, and documentation. Its goal is to be a mostly-compatible successor to the widely used Concurrent Versions System (CVS). To access our SVN, we need install SVN first. root@l2dcserver:~# aptitude install subversion When done, change to l2dc user, navigate thru /home/l2dc/Sources/L2DC directory and checkout project: l2dc@l2dcserver:~/Sources/L2DC$ svn checkout https://login.servegame.org/svn/dragonclaw --username cyberfox NOTE: L2DC doest have an public SVN Server. Here you need enter your own SVN login and password in order to access our files. Just configure --username with your own data. Accept certificate permanently, enter your password and wait a bit while files are downloaded from our repository.
7 de 11
28-03-2010 20:39
root@l2dcserver:~# ufw allow 7777 Rule added root@l2dcserver:~# ufw status Status: active To -OpenSSH 2106 7777 Action -----ALLOW ALLOW ALLOW From ---Anywhere Anywhere Anywhere
You are and L2DC Admin, edit your config files now and prepare everything to Server startup. Now Server is fully installed. To start login server, game server and community server, set them as executables and run it. l2dc@l2dcserver:~$ chmod +x Server/gameserver/GameServer_loop.sh Server/login/LoginServer_loop.sh Server/community/CommunityServer_loop.sh Run Servers and have fun!
8 de 11
28-03-2010 20:39
#!/bin/bash # # gameserver Starts L2DC Server # # chkconfig: - 66 34 # description: L2DC Server # processname: gameserver set -e DESC="GameServer" L2DIR="/home/l2dc/Server" # Directory with L2DC L2USER="l2dc" # User under which L2DC is running GADDR="127.0.0.1" # IP address of Game server GPORT="YOURGAMESERVERPORT" # Port of game server GCPORT="YOURTELNETPORT" # Telnet port of game server GPASS="YOURTELNETPASS" # Password for telnet to game server DOWNTIME="" test $# -gt 1 && DOWNTIME=$(echo $2 | sed -e 's/[^0-9]*//g') test "$DOWNTIME" || DOWNTIME=10 # Default shutdown/restart time ############################# g_start() { echo -n " gameserver: " if nc -z $GADDR $GPORT ; then echo "already running" else cd "$L2DIR/gameserver" || exit 1 sudo -u $L2USER ./GameServer_loop.sh & echo "started" fi }
g_stop() { ACTION=$1 echo -n " gameserver: " if ! nc -z $GADDR $GPORT ; then echo "not running" else expect -c " spawn telnet $GADDR $GCPORT expect \"Password:\" send \"$GPASS\r\" expect \"\[L2J\]\" send \"announce Server will $ACTION in $DOWNTIME seconds\r\" sleep 1 send \"$ACTION $DOWNTIME\r\" sleep 1 send \"quit\r\" " > /dev/null for ((i=$DOWNTIME ; i>0 ; i--)) ; do echo -ne "\r gameserver: $i \r" sleep 1 done echo -n " gameserver: " test "$ACTION" = "restart" && echo "restarted" || echo "stopped" fi } g_shutabort() { echo -n " gameserver: " if ! nc -z $GADDR $GPORT ; then echo "not running" else expect -c " spawn telnet $GADDR $GCPORT expect \"Password:\" send \"$GPASS\r\" expect \"\[L2J\]\" sleep 1 send \"abort\r\" sleep 1 send \"quit\r\" " > /dev/null echo "shutdown or restart aborted" fi }
g_status() { echo -n " gameserver: " nc -z $GADDR $GPORT && echo "running" || echo "not running" }
###################### cd "$L2DIR" || exit 1 case "$1" in start) echo "Starting $DESC: " g_start ;; stop) echo "Stopping $DESC:" g_stop shutdown ;; restart|force-reload) echo "Restarting $DESC: " g_stop restart ;; status) echo "Status of $DESC:" g_status ;; abort) echo "Aborting shutdown or restart of $DESC:" g_shutabort ;; *) echo "Usage: $0 {start|stop|restart|force-reload|status|abort}" >&2 exit 1 ;; esac exit 0 Now create /etc/init.d/l2dclogin and set it as executable: /etc/init.d/l2dclogin
9 de 11
28-03-2010 20:39
#!/bin/bash # # l2dclogin Starts L2DC LoginServer # # chkconfig: - 65 35 # description: L2DC Login # processname: l2dclogin set -e DESC="L2DCLogin" L2DIR="/home/l2dc/Server" # Directory with L2DC L2USER="l2dc" # User under which L2DC is running LADDR="127.0.0.1" # IP address of Login server LPORT="YOURLSPORT" # Port of login server LCPORT="YOURTELNETLSPORT" # Telnet port of login server LPASS="YOUTELNETLSPASSWD" # his password DOWNTIME="" test $# -gt 1 && DOWNTIME=$(echo $2 | sed -e 's/[^0-9]*//g') test "$DOWNTIME" || DOWNTIME=10 # Default shutdown/restart time ############################# l_start() { echo -n " loginserver: " if nc -z $LADDR $LPORT ; then echo "already running" else cd "$L2DIR/login" || exit 1 sudo -u $L2USER ./LoginServer_loop.sh & echo "started" fi }
l_stop() { echo -n " loginserver: " if ! nc -z $LADDR $LPORT ; then echo "not running" else expect -c " spawn telnet $LADDR $LCPORT expect \"Password:\" send \"$LPASS\r\" expect \"\[L2J\]\" send \"shutdown 1\r\" sleep 1 send \"quit\r\" " > /dev/null echo "stopped" fi }
l_status() { echo -n " loginserver: " nc -z $LADDR $LPORT && echo "running" || echo "not running" }
###################### cd "$L2DIR" || exit 1 case "$1" in start) echo "Starting $DESC: " l_start ;; stop) echo "Stopping $DESC:" l_stop ;; status) echo "Status of $DESC:" l_status ;; *) echo "Usage: $0 {start|stop|status}" >&2 exit 1 ;; esac exit 0 Well done. For now on, you will be able to start and stop login and gameserver by doing: root@firefox:~# service gameserver start root@firefox:~# service gameserver stop root@firefox:~# service l2dclogin start root@firefox:~# service l2dclogin stop
Realtime Logs
We can open one or two local terminals locally, SSH to our Server and start to watch over Server output logs realtime. This is quite easy to do. Using tail -f command. We can watch over any logs this way. The most needed ones are chat.log and stdout.log. You might take a look on GMAudit logs too, just point tail to desired log. Here is an good example: chat.log l2dc@l2dcserver:~$ tail -f -n 200 /home/l2dc/Server/gameserver/log/chat.log stdout.log l2dc@l2dcserver:~$ tail -f -n 200 /home/l2dc/Server/gameserver/log/stdout.log You can close tail with a ctrl + c or use screen command to run multiple logs on same terminal (l2dc@l2dcserver:~$ man screen for details). Personally I open both chat and stdout on two separated terminals. You can watch any system or game logs with that command.
Final Considerations
I think its it. I really hope can help you have a bit more structured and secure Production Servers. I put some of my experience in this guide, but Im not a coder or Linux Guru. I did a LOT of research to provide most complete, secure and good data available, but this guide may have flaws. If you know better ways/fixes to do anything, let me know. Feedback and fixes on this original work are welcome. Thanks for all feedback so far. If you find this guide useful, please consider sending a donation via PayPal? to donations@l2-adrenaline.com. You will be informed of guide updates. Thank you.
Revision History
Revision 1.0 07/03/2010 Initial release. Revision 1.1 08/03/2010 Added Realtime Logs Section. Revision 1.2 11/03/2010 Added Java Optimization Section Added MySQL Optimization Section Added Sending Logfiles via Email Section Revised DynDNS Section Revised Automatic MySQL Server sanity check and backup Section Configurable OSSEC Mail Alerts.
10 de 11
28-03-2010 20:39
11 de 11
28-03-2010 20:39