Overview1. Apache2基本配置2. 配置Apache2支持Perl CGI程序2.1 创建一个Perl网站2.2 配置Apache服务器3. 可能遇到的一些错误3.1 500 Internal Server Error3.2 503 Service Unavailable3.3 404 Not Found3.4 403 Forbidden4. 小结参考文章 Overview 这次我们开发Bastion4服务器使用了JAVA+Perl的架构，后端用Perl做服务器提供Webservice，用JAVA框架Struts接收处理用户请求，再跟Perl服务器交互。 我们使用Apache2作为Perl服务器，由于Apache2默认并不支持Perl，因此需要简单配置一下，使得Apache2以CGI的方式支持Perl运行。在配置的过程中，参考了一些网页，但由于各个网页都没有完整地描述配置过程（至少在我们的服务器上是这样），所以这里记录一下我们配置的全过程。 1. Apache2基本配置 我们为Bastion4申请了一个新的云服务器，版本为NeCTAR Ubuntu 16.04 LTS x86_64，自带了Apache2服务器，下面简单列出了Apache2的一些基本信息： /etc/apache2/ Apache2的配置文件目录 /var/www/ Apache2的网站存放目录 /var/log/apache2/ Apache2的日志存放目录 /etc/apache2/apache2.conf Apache2的配置主文件，以前的Apache版本中，主配置文件名字叫httpd.conf，所以很多网页中还用到这个名字，不知道的话会造成很多混淆。尽管apache2.conf是主配置文件，但是多数具体的配置信息并不是写在这个文件中的，/etc/apache2目录中有还有几个文件夹分别记录了几个模块的配置信息，apache2.conf负责把他们导入整合在一起。 /etc/apache2/sites-enabled/ 看名字就可以明白，Apache2的网站配置文件一般都是放在这个目录中的，这个目录下的000-default.conf是我们经常要修改的配置文件。 我们假定Apache存放网站的根目录是/var/www/，如果不确定(因为默认好像是/var/www/html这个目录)，打开/etc/apache2/apache2.conf目录，查看下面的配置： Options Indexes FollowSymLinks AllowOverride None Require all granted 如果在你的配置里是 修改成 这样，当你把一个名叫Mywebsite的网站(通常是一个文件夹)，扔到/var/www中时，你就可以以http://localhost/Mywebsite/访问到这个网站了。 如果你的配置是 ，那你需要把你的网站扔到/var/www/html中，才能使用http://localhost/Mywebsite/访问，这是因为 设置了Apache的根目录，当你使用http://****/Mywebsite访问时，Apache会去当前的根目录/Mywebsite找这个网站。 由于Apache的端口号默认是80，而不加端口号的url访问都会被服务器默认定向到80端口，因此这里不需要添加端口号，如果你手动将Apache端口号修改成了别的端口号（比如8888），那你需要使用http://localhost:8888/Mywebsite/访问这个网站。 2. 配置Apache2支持Perl CGI程序 2.1 创建一个Perl网站 在/var/www下创建网站的目录，我们创建一个名字叫cgi-bin的网站作为例子： mkdir /var/www/cgi-bin 需要使用管理员权限的命令，请自己加上sudo。 在/var/www/cgi-bin中创建一个cgi_test.pl脚本，输入下面的内容： #!/usr/bin/perl -w use warnings; use CGI qw(:standard); #! must use 'my' to define a variable print header; my $now_string = localtime(); print "Hello, CGI using Perl! It's $now_string NOW! "; 为cgi_test.pl添加可执行权限： chmod +x /var/www/cgi-bin/cgi_test.pl 在命令行运行cgi_test.pl： /var/cgi-bin/www/cgi_test.pl 会得到下面的结果： Content-Type: text/html; charset=ISO-8859-1 Hello, CGI using Perl! It's Mon Aug 1 03:35:42 2016 NOW! 成功运行这个perl脚本需要先安装perl的CGI库 尽管现在我们可以在本地以命令行的形式运行这个perl脚本，但还是不能让这个脚本在服务器中运行，访问http://localhost:8888/cgi-bin/cgi_test.pl，浏览器会直接显示整个脚本的内容： #!/usr/bin/perl -w use warnings; use CGI qw(:standard); #! must use 'my' to define a variable print header; my $now_string = localtime(); print "Hello, CGI using Perl! It's $now_string NOW! "; 而不是只把脚本打印的内容显示出来，所以，接下来我们继续配置Apache服务器。 2.2 配置Apache服务器 打开/etc/apache2/sites-enabled/000-default.conf配置文件，找到下面的配置信息： ... ServerAdmin webmaster@localhost DocumentRoot /var/www ... ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined 我们需要添加一些配置信息，添加之后，000-default.conf的内容如下： ... ServerAdmin webmaster@localhost DocumentRoot /var/www ScriptAlias /cgi-bin/ /var/www/cgi-bin/ AllowOverride all Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all AddHandler cgi-script .cgi .pl ... ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined 很容易看得出来，这部分配置主要是用来添加Apache对perl的支持。 默认情况下，Apache并没有启用CGI模块，我们可以从/etc/apache2/mods-enabled/中确认这点。 ls -l /etc/apache2/mods-enabled/ | grep cgi 显示结果为空。 ls -l /etc/apache2/mods-available/ | grep cgi 显示下面的结果： -rw-r--r-- 1 root root 74 Mar 19 09:48 authnz_fcgi.load -rw-r--r-- 1 root root 58 Mar 19 09:48 cgi.load -rw-r--r-- 1 root root 115 Mar 19 09:48 cgid.conf -rw-r--r-- 1 root root 60 Mar 19 09:48 cgid.load -rw-r--r-- 1 root root 89 Mar 19 09:48 proxy_fcgi.load -rw-r--r-- 1 root root 89 Mar 19 09:48 proxy_scgi.load 从名字上就可以看出来，mods-enabled中存放的是已经启用的模块，mods-available中存放的是所有可用的模块，所以启用CGI模块变得很简单，把mods-available中的相关文件在mods-enabled中创建软连接就可以了。 在mods-enabled中创建软连接，指向mods-available中的cgid.*文件： ln -s /etc/apache2/mods-available/cgid.load /etc/apache2/mods-enabled/ ln -s /etc/apache2/mods-available/cgid.conf /etc/apache2/mods-enabled/ 再次查看mods-enabled： ls -l /etc/apache2/mods-enabled/ | grep cgi 显示结果为： lrwxrwxrwx 1 root root 37 Jul 24 11:55 cgid.conf -> /etc/apache2/mods-available/cgid.conf lrwxrwxrwx 1 root root 37 Jul 24 11:55 cgid.load -> /etc/apache2/mods-available/cgid.load 重启Apache服务器： service apache2 restart 或者重新载入配置文件: service apache2 reload 稳妥的方式是restart Apache服务器，而不只是reload服务器，参见3.2。 在浏览器中访问：http://localhost:8888/cgi-bin/cgi_test.pl就会显示： Hello, CGI using Perl! It's Mon Aug 1 03:48:37 2016 NOW! 可以看到perl脚本在Apache服务器中以CGI脚本的形式运行了。 3. 可能遇到的一些错误 实际上，如果你严格按照上面的步骤，基本上不会出现错误，但是在这里，还是列出一些常见的错误，以便真的遇到这些问题时可以快速查看。 本节主要取自Perl/CGI script with Apache2，所以里面的脚本名字（这里是echo.pl，脚本的路径（这里是/var/cgi-bin而不是/var/www/cgi-bin）和错误信息都沿用了这篇文章的内容，与本文上面使用的脚本名字，脚本路径和脚本内容内容稍有不同，但也都大同小异。 3.1 500 Internal Server Error 如果你使用浏览器访问perl脚本时，看到500 Internal Server Error错误，打开Apache的错误日志/var/log/apache2/error.log。 如果显示下面的错误信息： [Wed Mar 19 15:19:15.740781 2014] [cgid:error] [pid 3493:tid 139896478103424] (8)Exec format error: AH01241: exec of '/var/cgi-bin/echo.pl' failed [Wed Mar 19 15:19:15.741057 2014] [cgid:error] [pid 3413:tid 139896186423040] [client 192.120.120.120:62309] End of script output before headers: echo.pl 说明脚本的第一行sh-bang line没有正确指向'perl'的安装路径，检查你的perl脚本，确认第一行是下面的样子： #!/usr/bin/perl 其实这样的错误非常罕见，除非你是新手，而且又完全自己手写了一段perl脚本。 如果显示下面的错误信息： No such file or directory: AH01241: exec of '/var/cgi-bin/echo.pl' failed [Wed Mar 19 15:24:33.505429 2014] [cgid:error] [pid 3412:tid 139896261957376] [client 192.120.120.120:58087] End of script output before headers: echo.pl 说明echo.pl是DOS格式，而非Unix格式，如果你经常的是Windows，或者喜欢在Windows下写好脚本再上传到Unix/Linux服务器中，那么这会是一个常见而且通用的错误。使用dos2unix命令转换脚本的格式： dos2unix /var/cgi-bin/echo.pl 系统默认可能并没有装dos2unix命令，需要自己安装一下。如果你用的是Ubuntu，用sudo apt install dos2unix安装。 如果显示下面的错误信息： [Wed Mar 19 15:40:31.179155 2014] [cgid:error] [pid 4796:tid 140208841959296] (13)Permission denied: AH01241: exec of '/var/cgi-bin/echo.pl' failed [Wed Mar 19 15:40:31.179515 2014] [cgid:error] [pid 4702:tid 140208670504704] [client 192.120.120.120:60337] End of script output before headers: echo.pl 说明你没有为perl脚本添加可执行权限，使用chmod命令很容易更正这个错误： chmod +x /var/cgi-bin/echo.pl 如果显示下面的错误信息： Wed Mar 19 16:02:20.239624 2014] [cgid:error] [pid 4703:tid 140208594970368] [client 192.120.120.120:62841] malformed header from script 'echo.pl': Bad header: hi 上面错误对应的脚本： #!/usr/bin/perl use strict; use warnings; print "hi\n"; print qq(Content-type: text/plain\n\n); 在perl脚本输出Content-type之前输出了别的字符，而浏览器解析的时候把那些字符当做了Content-type，所以报了Bad header错误。所以，不要在print qq(Content-type: text/plain\n\n);之前，输出别的字符。 如果显示下面的错误信息： [Wed Mar 19 16:08:00.342999 2014] [cgid:error] [pid 4703:tid 140208536221440] [client 192.120.120.120:59319] End of script output before headers: echo.pl 还是一个跟header相关的问题，说明你的脚本在打印Content-type之前就出了错误或者异常，error.log中也可能在上面的错误信息之前提供其他更具体的相关信息。所以，请仔细检查打印Content-type之前的perl代码。 关于End of script output before headers错误，原文作者认为可能与Premature end of script headers是同样的原因。 3.2 503 Service Unavailable 如果在本文2.2节为mods-enabled创建了软连接之后，并及时重载了apache，会报下面的错误： [Wed Mar 19 15:30:22.515457 2014] [cgid:error] [pid 3927:tid 140206699169536] (22)Invalid argument: [client 192.120.120.120:58349] AH01257: unable to connect to cgi daemon after multiple tries: /var/cgi-bin/echo.pl 我猜reload只是重新载入了服务器配置信息，并未将CGI进程启动，所以尽管已经配置了，但是由于CGI模块并未启动，所以自然也就没法连接CGI的守护进程。 所以，如果你只是修改了配置文件，reload就可以了，如果你启用或禁用了某个模块，需要restart，因为所有启用的模块，是在服务器启动过程中启动的。 稳妥的方式是restart Apache服务器，而不只是reload服务器。 3.3 404 Not Found 如果显示下面的错误信息： [Wed Mar 19 15:35:13.487333 2014] [cgid:error] [pid 4194:tid 139911599433472] [client 192.120.120.120:58339] AH01264: script not found or unable to stat: /usr/lib/cgi-bin/echo.pl 而echo.pl确实已经存在了，那么检查/etc/apache2/sites-enabled/000-default.conf中的DocumentRoot和ScriptAlias是否配置正确。 3.4 403 Forbidden 如果你遇到403 Forbidden错误，问题一般也出现在/etc/apache2/sites-enabled/000-default.conf这里。检查 ，确保里面涉及到权限的语句正确配置了。 4. 小结 以CGI的方式运行perl是最直接最原始的方式，如果你已经成功地以CGI形式运行了perl脚本，建议你尝试下面的方式： PSGI： 更灵活也更高效的方式。 Perl Dancer或者Mojolicious：成熟的perl服务器框架，非常易用。 参考文章 Background start Linux, install Apache2 在apache下以cgi方式运行perl
Overview1. MySQL安装2.MySQL命令3. MySQL通用配置3.1 MySQL会话时间4. 远程MySQL配置4.1 激活MySQL的网络设置4.2 授权4.3 配置防火墙5. 参考内容 Overview 今天跟Young在做secretepdb这个项目时，需要使用Hibernate连接数据库，为了方便一起开发，就直接连接了我们在阿里云服务器上的MySQL，遇到了一些问题，有些是本地数据库和远程数据库的共性问题，有些则是连接远程数据库才会遇到的问题，在这里记录，以便共享和以后查阅。 1. MySQL安装 在Ubuntu上，使用如下命令安装： sudo apt-get install mysql-server 安装过程中会要求配置MySQLroot用户的密码，要牢记这个密码，不然会很麻烦。 安装之后的目录在:/etc/mysql，其中，my.cnf就是MySQL的配置文件，我们对MySQL所有的配置几乎都是在这里完成的。 2.MySQL命令 因为在不同版本的服务器，甚至使用不同方式安装的MySQL，启动，关闭MySQL等命令都有所不同，所以我们在这里记录一下在我们的服务器(Ubutun 14.04)上适用的这些命令，方便我们使用。 Ubuntu上mysql配置文件位置：/etc/mysql/my.cnf mysql关闭命令：/etc/init.d/mysql stop mysql启动命令：/etc/init.d/mysql start mysql重启命令：/etc/init.d/mysql restart 3. MySQL通用配置 3.1 MySQL会话时间 无论是连接本地MySQL还是远程服务器上的MySQL，通常来说设置一组比较长的会话时间总是好的，在/etc/mysql/my.cnf中添加如下三句代码： wait_timeout=31536000 interactive_timeout=31536000 connect_timeout=31536000 4. 远程MySQL配置 如果你想让你的网站连接一个远程服务器上的MySQL，而不是网站所在的服务器上的服务器，那么你需要配置远程服务器上的MySQL，才能像访问本机MySQL一样访问远程MySQL。 我们远程MySQL以及服务器配置如下： 服务器地址：120.24.231.154 MySQL端口号：3306 4.1 激活MySQL的网络设置 默认情况下，为了安全起见，MySQL的配置是只支持本机访问的，因此我们需要修改/etc/mysql/my.cnf中的配置，如果/etc/mysql/my.cnf中有 skip-networking 这句代码，将它注释掉： #skip-networking 高版本的MYSQL中默认已经没有了这项配置。 将 bind-address = 127.0.0.1 改为： bind-address = 120.24.231.154 这里的120.24.231.154就是远程MySQL所在的服务器的IP地址。 但是这样的问题就是，当你需要本地连接数据库时，还要再改回来，很不方便，所以可以直接将这一句注释掉，这样就允许所有的IP地址远程连接了，唯一的问题在于没那么安全。 保存并关闭配置文件，并重启mysql服务器: /etc/init.d/mysql restart 4.2 授权 在修改配置允许了MySQL接受远程访问之后，还需要授权，使MySQL允许某一个IP地址或者所有的IP地址的远程连接。 登录到远程MySQL所在的服务器，使用root账号打开MySQL: mysql -u root -h localhost -p 这里输入密码之后就可以登录到MySQL。 进入MySQL数据库: use mysql; 使用下面语句： update user set host='%' where user='root' and host='localhost'; 将host设置为%表示任何ip都能连接mysql，当然也可以将host指定为某个ip。 刷新权限表，使配置生效： flush privileges; 如果想取消授权，关闭远程连接，恢复mysql的默认设置（只能本地连接），可以通过以下步骤操作： use mysql #打开mysql数据库 #将host设置为localhost表示只能本地连接mysql update user set host='localhost' where user='root'; flush privileges; #刷新权限表，使配置生效 其中#后面的为注释，操作MySQL时，记得去掉，只复制#前面的命令就可以。 4.3 配置防火墙 一般来说，经过上面的配置，已经可以远程连接服务器上的MySQL了，因为安装MySQL的时候，MySQL使用的3306端口就会被打开。 当然，也有可能出于安全问题等被关闭，使用下面的方式检查端口状态。 检查3306端口是否被打开： netstat -anp | grep 3306 在我们的服务器上显示如下信息： tcp 0 0 120.24.231.154:3306 0.0.0.0:* LISTEN 21080/mysqld tcp 0 0 120.24.231.154:3306 221.216.162.253:12155 ESTABLISHED 21080/mysqld tcp 0 0 120.24.231.154:3306 221.216.162.253:12042 ESTABLISHED 21080/mysqld 说明我们的3306端口已经打开了。 如果3306端口没打开，使用下面的命令打开： iptables -A INPUT -p tcp -i eth0 --dport 3306 -j ACCEPT 如果想关闭3306端口，使用下面的命令： iptables -A OUTPUT -p tcp -i eth0 --dport 3306 -j DROP 配置完成后，使用 service iptables restart 重新启动iptable。 5. 参考内容 主要参考了下面的网址： 服务器开发环境搭建 [转] 阿里云配置mysql远程连接 Mysql远程连接配置 [转] linux iptables 端口 查看，打开，关闭