Devil May Code...

Vergil's Blog

今天帮客户配置了一台阿里云主机LNMP环境,特此记录。

云主机配置如下:

  • 系列 II 通用型n1 2核4GB
  • SSD云盘 40GB
  • 高效云盘 100GB
  • Ubuntu 16.04 64位

以下文章具体路径不贴出,#表示root用户的命令,$表示普通用户。

安全设置

主机初始化后使用root账号连接SSH

首先添加一个新的用户及相关家目录,由于私隐原因用username代替账户名

# mkdir /home/username
# useradd d /home/username username
# chown -R username:username /home/username
# passwd username
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

把用户加入到sudo用户组

# usermod -aG sudo username

尝试用这个新用户username登录后,感觉SHELL好像有点不对。。。

看一下/etc/passwd文件,发现这个用户用的shell是/bin/sh,并查看详细发现默认使用dash

# ll /bin/sh
lrwxrwxrwx 1 root root 4 Dec 14 18:54 /bin/sh -> dash*

强制把它改回bash,我在这里直接用更改软链的方式:

# ln -sf /bin/bash /bin/sh

或者可以这样修改:

# usermod -s /bin/bash username

复制bash配置模板文件到新用户的家目录:

# cp /etc/skel/.bashrc /home/username
# cp /etc/skel/.profile /home/username
# chown -R username:username /home/username

Tips:如果需要经常登录这台主机管理,建议使用神器robbyrussell/oh-my-zsh配置一个zsh使用,否则bash也凑合用了。

禁止root用户登录

修改/etc/ssh/sshd_config,找到PermitRootLogin并改为no。重启ssh服务:

# service ssh restart

退出登录,尝试一下不能用root用户登录即可,然后随后的操作都用普通用户进行。

禁止密码登录

如果你只是在固定的(本地,一台或多台)机器上管理这台主机,建议禁止密码登录。(密码认证会受到暴力攻击破解)

但如果你是不固定的主机上管理它,建议还是密码登录吧,但密码尽量设置复杂,不要被人家知道用户名。另外这台机器是帮客户配置的,我没有做这一步(职业操守)

如果你已经生成过密钥连接其他服务器,请跳过这一步,直接复制这个密钥。否则重新生成的话会让你登录不了其他服务器。以下操作是在你的本地电脑(不是这台服务器)上进行:

$ ssh-keygen -t rsa -b 4096

这样生成了两个文件id_rsa(私钥)和id_rsa.pub(公钥),存放在本地主机的~/.ssh下(MacOS或Linux系统),其他它会问你让你重复一个密码两次,如果不想在使用公钥的时候输入密码,可以留空。(不是主机的密码,但要谨记,输入密码后每次连接都要输入该密码,请根据自己的安全需要决定)。

然后可以使用scp命令把公钥复制到服务器上:

$ scp ~/.ssh/id_rsa.pub username@yourip:~

然后以username的身份登录服务器。登陆后,你会发现这个id_rsa.pub在你的家目录。确认~/.ssh目录是否存在,如果不存在需要创建该目录。

$ mkdir ~/.ssh

然后创建一个叫authorized_keys的文件:

$ touch ~/.ssh/authorized_keys

这个文件的内容是一系列允许登录这台服务器的公钥。把刚才远程复制过来的文件写入到这个文件中:

$ cat ~/id_rsa.pub >> ~/.ssh/authorized_key

修改一下目录和文件的访问权限:

$ chown -R username:username ~/.ssh
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_key

随后,退出登录然后再次登录看看是否不需要密码(或者需要创建密钥时的那个密码,如果你有设置的话)就能通过ssh登录这台服务器。

如果可以的话,那么就可以禁止密码登录这台主机了。编辑/etc/ssh/sshd_config文件,然后把PasswordAuthentication改为no

PasswordAuthentication no

然后重启ssh服务:

$ sudo service ssh restart

现在,你可以找一台其他电脑登录这个服务器看看:)

更新软件

$ sudo apt-get update && apt-get -y upgrade

配置防火墙

这里只是简单的用一下ufw配置,Ubuntu默认已经安装好这个软件。这里只允许2280端口访问,其他规则请按自己需求进行添加。

$ sudo ufw allow ssh
$ sudo ufw allow http/tcp
$ sudo ufw enable

修改完防火墙最好另开终端尝试能否连接ssh,别把自己困在外面了

磁盘管理

磁盘管理命令切换回root身份进行操作比较方便:

$ sudo su -

如文章开头所说,我这里买了两块硬盘,开通主机后只有一块挂载,另一块没有分区的。

使用以下命令查看系统文件信息和查看分区情况:

# df -hTl
# fdisk -l

使用fdisk对第二块磁盘/dev/vdb进行分区,这里不进行细分,这个盘作为数据盘使用的,分一个区使用全部空间。

# fdisk /dev/vdb

Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): m

Help:

  DOS (MBR)
   a   toggle a bootable flag
   b   edit nested BSD disklabel
   c   toggle the dos compatibility flag

  Generic
   d   delete a partition
   F   list free unpartitioned space
   l   list known partition types
   n   add a new partition
   p   print the partition table
   t   change a partition type
   v   verify the partition table
   i   print information about a partition

  Misc
   m   print this menu
   u   change display/entry units
   x   extra functionality (experts only)

  Script
   I   load disk layout from sfdisk script file
   O   dump disk layout to sfdisk script file

  Save & Exit
   w   write table to disk and exit
   q   quit without saving changes

  Create a new label
   g   create a new empty GPT partition table
   G   create a new empty SGI (IRIX) partition table
   o   create a new empty DOS partition table
   s   create a new empty Sun partition table

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p):

Using default response p.
Partition number (1-4, default 1):
First sector (2048-209715199, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-209715199, default 209715199):

Created a new partition 1 of type 'Linux' and of size 100 GiB.

Command (m for help): p
Disk /dev/vdb: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x628f3d56

Device     Boot Start       End   Sectors  Size Id Type
/dev/vdb1        2048 209715199 209713152  100G 83 Linux

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

格式化磁盘:

# mkfs -t ext4  /dev/vdb1
mke2fs 1.42.13 (17-May-2015)
Found a dos partition table in /dev/vdb1
Proceed anyway? (y,n) y
Creating filesystem with 26214144 4k blocks and 6553600 inodes
Filesystem UUID: 93b1be9f-d4b4-438b-9388-1815dc6b90ae
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

挂载磁盘到/data目录并查看:

# mkdir /data
# mount /dev/vdb1 /data/
# df -hl
Filesystem      Size  Used Avail Use% Mounted on
udev            2.0G     0  2.0G   0% /dev
tmpfs           396M  3.2M  393M   1% /run
/dev/vda1        40G  2.5G   35G   7% /
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
tmpfs           396M     0  396M   0% /run/user/1000
/dev/vdb1        99G   60M   94G   1% /data

安装软件

Tips:阿里云的主机默认使用阿里云镜像,如果是原版的Ubuntu,你可以看这里找一个比较快的镜像进行修改。

一切就绪后,现在开始安装软件,首先更新一下apt的软件包。

$ sudo apt-get update && apt-get -y upgrade
$ apt-get install -y software-properties-common curl
$ apt-get install -y build-essential dos2unix gcc git libmcrypt4 libpcre3-dev make python2.7-dev python-pip re2c supervisor unattended-upgrades whois vim libnotify-bin git

安装Nginx

$ sudo apt-get install nginx

Nginx开启服务的几种方式:

$ sudo service nginx start

或:

$ /etc/init.d/nginx

或:

$ /usr/sbin/nginx -c /etc/nginx/nginx.conf

-c参数表示指定nginx配置文件的位置。

重启服务:

$ service nginx restart

平滑重启:

$ /usr/sbin/nginx -s reload

关闭:

$ /usr/bin/nginx -s stop

安装MySQL

既然用阿里云的云主机,其实是建议买阿里云的RDS的,不过客户这边没提供,只能在本机上安装:

$ sudo apt-get install mysql-server mysql-client

安装过程中软件会提示你设置mysql的root密码

安装PHP(FPM)

$ sudo apt-get install -y php7.0 php7.0-cli php7.0-fpm php7.0-dev

安装所需扩展:

$ sudo apt-get install -y php7.0-mbstring php7.0-mysql php7.0-mcrypt \ 
  php7.0-curl php7.0-gd php7.0-bcmath php7.0-imap php7.0-xml php7.0-intl \
  php-memcache php-memcached php-redis php-mongodb php-msgpack
  

安装完成后可以看下版本信息和安装的模块:

$ php -v
PHP 7.0.13-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.13-0ubuntu0.16.04.1, Copyright (c) 1999-2016, by Zend Technologies
$ php -m
[PHP Modules]
bcmath
calendar
Core
ctype
curl
...

安装Composer

$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer

安装redis和memcached

$ apt-get install redis-server redis-tools redis-sentinelip
$ apt-get install memcached

安装nodejs相关

$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ sudo npm install -g gulp
$ sudo npm install -g bower
$ sudo npm install -g grunt-cli

部分软件配置

Nginx

/etc/nginx/nginx.conf修改了几个地方:

worker_processes 4;

events {
    worker_connections 65535;
    multi_accept on;
    use epoll;
}

http {
    ...
    keepalive_timeout 60;
    server_tokens off;
    server_names_hash_bucket_size 64;
    client_header_buffer_size 4k;
    open_file_cache max=65535 inactive=60s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 1;
    ...
}

/etc/nginx/fastcgi_params如下:

fastcgi_param   QUERY_STRING        $query_string;
fastcgi_param   REQUEST_METHOD      $request_method;
fastcgi_param   CONTENT_TYPE        $content_type;
fastcgi_param   CONTENT_LENGTH      $content_length;
fastcgi_param   SCRIPT_FILENAME     $request_filename;
fastcgi_param   SCRIPT_NAME         $fastcgi_script_name;
fastcgi_param   REQUEST_URI         $request_uri;
fastcgi_param   DOCUMENT_URI        $document_uri;
fastcgi_param   DOCUMENT_ROOT       $document_root;
fastcgi_param   SERVER_PROTOCOL     $server_protocol;
fastcgi_param   GATEWAY_INTERFACE   CGI/1.1;
fastcgi_param   SERVER_SOFTWARE     nginx/\$nginx_version;
fastcgi_param   REMOTE_ADDR         $remote_addr;
fastcgi_param   REMOTE_PORT         $remote_port;
fastcgi_param   SERVER_ADDR         $server_addr;
fastcgi_param   SERVER_PORT         $server_port;
fastcgi_param   SERVER_NAME         $server_name;
fastcgi_param   HTTPS               $https if_not_empty;
fastcgi_param   REDIRECT_STATUS     200;

配置虚拟主机

nginx.conf文件底部写了一句:include /etc/nginx/sites-enabled/*;

按照Ubuntu的默认配置,这个/etc/nginx/sites-enabled是放虚拟主机配置的,而这里的文件是一个软链接到/etc/nginx/sites-available。我觉得这样的目录分配挺好的,当然你不喜欢可以全部写到nginx.conf也没问题:)

/etc/nginx/sites-enabled添加一个文件your-hostname(自行更改),并写入一下内容:

server {
    listen 80;
    root /path/to/your/project/root;
    index index.html index.htm index.php;

    server_name your-hostname;

    sendfile off;
    access_log /var/log/nginx/your-hostname.log combined;
    error_log  /var/log/nginx/your-hostname-error.log error;
    client_max_body_size 100m;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }
}

写好虚拟主机配置后,软件到/etc/nginx/sites-enabled:

$ sudo ln -s /etc/nginx/sites-available/your-hostname /etc/nginx/sites-enabled/

多个虚拟主机建议写多个配置文件,如果你不想要这台虚拟主机,删掉/etc/nginx/sites-enabled的软链即可(意思就是说/etc/nginx/sites-available/的文件它不加载的,留着也没关系)

配置PHP

修改/etc/php/7.0/fpm/php.ini几个地方:

max_execution_time = 10
memory_limit = 1024M
upload_max_filesize = 10M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On

修改/etc/php/7.0/cli/php.ini几个地方:

max_execution_time = 0
max_input_time = -1
memory_limit = -1
error_reporting = E_ALL
display_errors = On
display_startup_errors = On

这两个配置文件是不同的,一个是fastcgi模式下的配置文件,就是用浏览器访问服务器时的配置。

cli就是在CLI(命令行)模式下的。一般来说使用这个模式是服务器的管理员(除非你可以被用户执行服务器的脚本,就需要谨慎设置了)

新建存放log的文件夹:

$ sudo mkdir /var/log/php/

修改/etc/php/7.0/fpm/php-fpm.conffpm全局配置:

emergency_restart_threshold = 10
emergency_restart_interval = 1m

修改/etc/php/7.0/fpm/pool.d/www.conf

listen = /run/php/php7.0-fpm.sock
listen.allowed_clients = 127.0.0.1
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 20
slowlog = /var/log/php/slowlog.log
request_slowlog_timeout = 5s

如果你写成

listen = 127.0.0.1:9000

则需要把nginx的配置文件改成:

location ~ \.php$ {
      ...
        fastcgi_pass 127.0.0.1:9000;
        ...
}

配置Opcache

可以在模块配置那里编辑/etc/php/7.0/fpm/conf.d/10-opcache.ini(文件名可能会不同)。也可以在php.ini底部[opcache]段修改(默认全部注释掉),

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.fast_shutdown=0
opcache.save_comments=0
opcache.huge_code_pages=1

Ok,配置好后,重启php-fpm和nginx:

$ sudo service php7.0-fpm restart
$ sudo nginx -s reload

配置MySQL

MySQL配置比较复杂,而且现在还没做MySQL Replication,先用默认配置。

关于MySQL配置的优化和高可用配置,建议订阅叶金荣老师的微信公众号老叶茶馆和吴炳锡老师的公众号MySQL Beginer

或者可以根据姜承尧老师的MySQL最佳配置进行修改。


最后做一下清理:

$ sudo apt-get -y autoremove
$ sudo apt-get -y clean

暂时先到这里,Bye


已有 2 条评论 »

  1. sam sam

    这篇文章真不错

  2. Wonderful information, With thanks.

添加新评论 »

在这里输入你的评论...

Powered by Typecho.