Thursday, August 29, 2013

Disable module apache

#LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_alias_module modules/mod_authn_alias.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
#LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
#LoadModule authz_user_module modules/mod_authz_user.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
#LoadModule authz_default_module modules/mod_authz_default.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
#LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
#LoadModule logio_module modules/mod_logio.so
#LoadModule env_module modules/mod_env.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
#LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
#LoadModule headers_module modules/mod_headers.so
#LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so

#LoadModule dav_module modules/mod_dav.so
#LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule info_module modules/mod_info.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so

#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so

#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule cache_module modules/mod_cache.so
LoadModule suexec_module modules/mod_suexec.so
#LoadModule disk_cache_module modules/mod_disk_cache.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule mem_cache_module modules/mod_mem_cache.so
#LoadModule cgi_module modules/mod_cgi.so
#LoadModule version_module modules/mod_version.so

#
# The following modules are not loaded by default:
#
#LoadModule cern_meta_module modules/mod_cern_meta.so
#LoadModule asis_module modules/mod_asis.so 

Wednesday, August 28, 2013

Enable log slow query mysql

In order to enable slow query logs for MySQL on your system you would need to do the following.
1st Step is to edit your my.cnf file which is located in your /etc directory.
vi /etc/my.cnfPlain Text
Once you have your my.cnf file open, then add the following 4 lines then save and exit the file.
[mysqld]
log-slow-queries
log-slow-queries=/var/log/mysql/slow-queries.log
long_query_time=1
Plain Text
Then create the file slow-queries.log. You can have the file in any spot you wish, as long as you define the path in your my.cnf.
touch /var/log/mysql/slow-queries.logPlain Text
Change the ownership of the file to be owned by MySQL.
chown mysql.mysql /var/log/mysql/slow-queries.logPlain Text
Lastly, you will need to restart mysqld for your changes to take place.
service mysqld restartPlain Text

Now you should have slow query logs enabled catching any MySQL query that took longer then 1 second to process.

Copy a folder linux


I'm a new Linux user. How do I copy a directory or folder under Linux operating system using command line options and bash shell?

You can use various command to copy a folder under Linux operating systems.

cp Command

cp is a Linux command for copying files and directories. The syntax is as follows:
 
cp source destination
cp dir1 dir2
cp -option  source destination
cp -option1 -option2  source destination
 
In this example copy /home/vivek/letters folder and all its files to /usb/backup directory:
 
cp -avr /home/vivek/letters /usb/backup
 
Where,
  • -a : Preserve the specified attributes such as directory an file mode, ownership, timestamps, if possible additional attributes: context, links, xattr, all.
  • -v : Explain what is being done.
  • -r : Copy directories recursively.

Example

Copy a folder called /tmp/conf to /tmp/backup:
$ cp -avr /tmp/conf/ /tmp/backup
Sample outputs:
HowTO: Copy Folder Linux Terminal Command
Fig.01: cp command in action

rsync Command

You can also use rsync command which is a fast and extraordinarily versatile file copying tool. It can make copies across the network. The syntax is as follows:
 
rsync -av /path/to/source /path/to/destination
rsync -av /path/to/source/ /path/to/destination/source
 
To backup my home directory, which consists of large files and mail folders to /media/backup, enter:
$ rsync -avz /home/vivek /media/backup
I can copy a folder to remote machine called server1.cyberciti.biz:
$ rsync -avz /home/vivek/ server1.cyberciti.biz:/home/backups/vivek
Where,
  • -a : Archive mode i.e. copy a folder with all its permission and other information including recursive copy.
  • -v : Verbose mode.
  • -z : With this option, rsync compresses the file data as it is sent to the destination machine, which reduces the amount of data being transmitted — something that is useful over a slow connection.
You can show progress during transfer using --progress or -P option:
$ rsync -av --progress /path/to/source/ /path/to/dest
Sample outputs:
Copy Folder Linux Commands [ rsync ]
Fig.02: rsync command in action

Thursday, August 22, 2013

Speed MySQL Query

Khi database của bạn lớn/nhiều hoặc lượng truy cập và liên tục , chắc chắn MySQL sẽ chiếm rất nhiều tài nguyên và khiến server load cao. Để hạn giảm load cho server , chúng ta có thể cache lại kết quả của các lần query vào bộ nhớ RAM. Tính năng này được MySQL hỗ trợ từ phiên bản 4.0.1 trở lên, để enable chức năng này chúng ta cần đặt các giá trị sau vào file /etc/my.cnf :
Code:
query_cache_type = 1
query_cache_size = 256M
query_cache_limit = 2M
query_cache_type : enable or disable tính năng query cache (enable = 1 ; disable = 0)
query_cache_size : lượng RAM dành cho việc cache query result.
query_cache_limit: dung lượng tối đa của một query result mà mình cho phép cache.
- Kiểm tra xem query cache đã được kích hoạt hay chưa :
Code:
mysql> show variables like '%query_cache%';
+------------------------------+-----------+
| Variable_name                | Value     |
+------------------------------+-----------+
| have_query_cache             | YES       |
| query_cache_limit            | 2097152   |
| query_cache_min_res_unit     | 4096      |
| query_cache_size             | 268435456 |
| query_cache_type             | ON        |
| query_cache_wlock_invalidate | OFF       |
+------------------------------+-----------+
- Kiểm tra xem query cache đã hoạt động hay chưa :
Code:
mysql> show status like '%qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 17034    |
| Qcache_free_memory      | 36995488 |
| Qcache_hits             | 4455579  |
| Qcache_inserts          | 702176   |
| Qcache_lowmem_prunes    | 87400    |
| Qcache_not_cached       | 76260    |
| Qcache_queries_in_cache | 20198    |
| Qcache_total_blocks     | 78340    |
+-------------------------+----------+
Vài thông số quan trọng cần chú ý :
Qcache_free_memory : lượng RAM hiện tại còn trống (chưa sử dụng) cho việc cache. Nếu thông số này quá cao bạn có thể giảm query_cache_size xuống , nếu quá thấp thì nâng query_cache_size lên.
Qcache_hits : số lượng query được lấy trong cache ra sử dụng thay vì phải thực hiện “real query” đến CSDL.
Qcache_inserts : số lượng query đã được add vào cache.
Qcache_lowmem_prunes : mỗi khi vùng nhớ dành cho việc cache bị hết (Qcache_free_memory thấp), khi add thêm query vào cache MySQL cần phải giải phóng 1 ít bộ nhớ để chứa query này. Mỗi lần thu hồi vùng nhớ , con số này tăng lên 1. Nếu số này quá lớn chứng tỏ lượng RAM dành cho việc cache(query_cache_size) không đủ và cần phải tăng lên. Nếu số này bằng 0 thì lượng RAM dành cho cache quá lớn , cần giảm lại.
Qcache_queries_in_cache : số lượng query hiện tại đang được cache.
MySQL cung cấp cho bạn những bản my.cnf cho từng cấu hình, những mẫu cấu hình này bạn có thể xem trong thư mục /usr/share/mysql/
Tùy vào đáp ứng của tài nguyên bạn có thể sử dụng những cấu hình khác nhau. Để xem cấu hình nào phù hợp với mình bạn có thể dùng lệnh cat để xem sẽ thấy hướng dẫn cơ bản cho cấu hình đó.
Để lấy cấu hình my-large.cnf bạn muốn cho MySQL, bạn dùng lệnh: cp -f /usr/share/mysql/my-large.cnf /etc/my.cnf
Sau đó, restart lại mysql: /sbin/service mysqld restart
Một số hướng dẫn để tự tinh chỉnh cấu hình MySQL:
[mysqld]
key_buffer = 64M (cho hệ thống 1GB RAM), 128M (cho 2GB RAM), 256 (cho 4GB RAM)
join_buffer_size 
= 1M (cho 1GB RAM), 2M (cho 2GB RAM), 4M (cho 4GB RAM)
sort_buffer_size = 1M (cho 1GB RAM), 2M (cho 2GB RAM), 4M (cho 4GB RAM)
read_buffer_size = 1M (cho 1GB RAM), 2M (cho 2GB RAM), 4M (cho 4GB RAM)
read_rnd_buffer_size = 768K (cho 1GB RAM), 1536K (cho 2GB RAM), 3072K for 4GB (RAM)
myisam_sort_buffer_size = 32M (cho 1GB RAM), 64M (cho 2GB RAM), 128 (cho 4GB RAM)
query_cache_type = 1 (0 nghĩa là tắt, 1 là bật và 2 là chế độ "demand")
query_cache_size = 32M (cho 1GB RAM), 63M (cho 2GB RAM), 128M (cho 4GB RAM)
query_cache_limit = 1M (cho 1GB RAM), 2M (cho 2GB RAM), 4M (cho 4GB RAM)
thread_cache_size = 8 đến 64 tùy vào tài nguyên thừa của RAM
[isamchk]
key_buffer và sort_buffer = 64M (cho 1GB RAM), 128M (cho 2GB RAM), 256M (cho 4GB RAM)
read_buffer và write_buffer = 16M (cho 1GB RAM), 32M (cho 2GB RAM), 64M (cho 4GB RAM)
[myisamchk]
key_buffer và sort_buffer = 64M (cho 1GB RAM), 128M (cho 2GB RAM), 256M (cho 4GB RAM)
read_buffer và write_buffer = 16M (cho 1GB RAM), 32M (cho 2GB RAM), 64M (cho 4GB RAM)

Tối Ưu Hóa Và Bảo Mật Apache

1. Edit một số directive default trong httpd.conf để giảm thiểu việc lộ lọt thông tin cấu hình của máy chủ hoặc các tác vụ ko cần thiết:
TraceEnable Off : Disable TRACE request method
ServerSignature Off : Disable việc thể hiện các thông tin về máy chủ (apache version, các mod đang sử dụng ...) ở footer các page do server generate ra, một phần nào đó cũng giảm thiểu được bandwidth cho các bạn.
ServerTokens Prod : Chỉ thể hiện "Server: Apache" trong header trả về thay vì "Server: Apache 2.2.16" hoặc "Server: Apache 2.2.16/mod_abc,mod_xyz" ...
UseCanonicalName Off : Disable việc sử dụng CanonicalName.
HostnameLookups Off : Disable tính năng lookup hostname từ IP address của client.

2. Giảm thời gian Timeout và enable KeepAlive: việc này sẽ làm giảm thiếu số lượng socket connection được mở đến server, thời gian tồn tại của chúng trên server ...
Code:

Timeout 15
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 7

3. Tính toán số lượng MaxClients hợp lý: Việc này nhằm đảm bảo nếu như apache bị flood cũng sẽ ko sử dụng hết tài nguyên của máy chủ khiến máy chủ bị treo, cũng như việc cấp phát lượng bộ nhớ phù hợp cho httpd.
Em viết sẵn 1 cái script dùng để tính toán số lượng MaxClient dành cho máy chủ đang chạy ở mode DSO. Với các mode khác thì mọi người dựa vào ý tưởng rồi tính toán cho phù hợp:
Code:


#!/bin/bash
# Script compute MaxClient for Apache
# Coded by Ikazuchi[at]quantrilinux.com
# Date: 14/05/2012

# Get total MEM
TOTAL_MEM=$(head -1 /proc/meminfo | awk '{print $2}')

# Get total Memory is being used
TOTAL_MEM_USED=$(free | grep 'buffers/cache' | awk '{print $3}')

# Get average memory of 1 process httpd
count=0
httpd_mem=0

for process_mem in `ps -ylC httpd --sort:rss | awk '{print $8}' | grep -v RSS`
do
let "count+=1"
let "httpd_mem+=$process_mem"
done

# Average memory per process
HTTPD_AVG_MEM=$(( $process_mem / $count ))

# Get total memory used for httpd:
HTTPD_TOTAL_MEM=$(( $TOTAL_MEM - $TOTAL_MEM_USED + $httpd_mem ))

MAX_CLIENT=$(( $HTTPD_TOTAL_MEM / $HTTPD_AVG_MEM ))

# Final result
echo -e "Total RAM in this server:\t\t $TOTAL_MEM KB"
echo -e "Total RAM is being used:\t\t $TOTAL_MEM_USED KB"
echo -e "Total RAM will be used for httpd:\t $HTTPD_TOTAL_MEM KB"
echo -e "Average RAM per process httpd:\t\t $HTTPD_AVG_MEM KB"
echo -e "Recommend MaxClients value:\t\t $MAX_CLIENT"

Kết quả ví dụ sẽ như sau:
Code:
Total RAM in this server:         8115520 KB
Total RAM is being used:         4546728 KB
Total RAM will be used for httpd:     4584432 KB
Average RAM per process httpd:         4611 KB
Recommend MaxClients value:         994

Giám sát hệ thống Linux với netstat

Netstat là một công cụ hữu ích của Linux cho phép bạn kiểm tra những dịch vào nào đang kết nối đến hệ thống của bạn. Nó rất hữu ích trong việc phân tích cái gì đang xảy ra trên hệ thống của bạn khi bạn cố gắng ngăn chặn một cuộc tấn công nhằm vào nó. Bạn có thể tìm thêm thông tin như có bao nhiêu kết nối được tạo ra trên một cổng, địa chỉ IP nào đang kết nối đến và nhiều thông tin khác nữa. Netstat đi kèm trong hầu hết các bản phân phối của Linux vì vậy nó nên được cài đặt trên hệ thống của bạn.

Khởi động một shell terminal trên hệ thống của bạn và chạy câu lệnh sau:

Code:

# netstat -ant


Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 ::ffff:192.168.1.19:80 ::ffff:192.168.1.240:63049 TIME_WAIT
tcp 0 0 ::ffff:192.168.0.19:80 ::ffff:192.168.1.240:62793 TIME_WAIT
tcp 0 0 ::ffff:192.168.1.19:80 ::ffff:192.168.1.240:62795 TIME_WAIT

Những thông tin xuất ra hầu hết đều rất dài. Như ở trên là một ví dụ về thông tin xuất ra. Như bạn có thể thấy trong dữ liệu ở trên có một kết nối được tạo ra từ 192.168.1.240 đến máy tính của chúng ta ở cổng 80 sử dụng giao thức TCP và kết nối đang ở trạng thái TIME_WAIT. Những thông tin xuất ra này sẽ cho bạn biết thông tin về tất cả các cổng trên hệ thống của bạn, không chỉ riêng cổng 80.

Điều đầu tiên bạn cần nhận thức là những thông tin này rất lớn nhưng không được dùng nhiều. Vì vậy chúng ta cần phải tổ chức lại nó. Ở đây có một vài thủ thuật chúng ta dùng để phân tích trạng thái tự nhiên của kết nối được tạo ra bởi hệ thống của chúng ta. Điều đầu tiên chúng ta cần làm là suy nghĩ xem những dịch vụ nào mà chúng ta muốn phân tích. Thông thường, cổng 80 là cổng mặc định cho web server, và cổng 3306 là cổng mặc định của MySQL. Vì vậy chúng ta sẽ dùng lệnh sau để xem cái gì đang diễn ra trên cổng 80:


Code:
# netstat -ant | grep 80



Bây giờ chúng ta sẽ có một danh sách các kết nối, nhỏ hơn lần trước, nhưng vẫn quá lớn để có thể nắm bắt hết. Vì vậy chúng ta sẽ dùng thêm lệnh "Wc -l" để đếm số dòng xuất ra để xem có bao nhiêu kết nối đến cổng 80:


Code:

# netstat -ant | grep 80 | wc -l 

625
# netstat -ant | grep 3306 | wc -l 

61
Bây giờ nếu muốn có một bức tranh toàn cảnh về những gì đang diễn ra trên hệ thống về các kết nối, chúng ta làm như sau:


Code:
# netstat -ant | awk '{print $6}' | sort | uniq -c | sort -n 

1 established)
1 Foreign
4 FIN_WAIT2
8 LISTEN
16 CLOSE_WAIT
134 ESTABLISHED
409 TIME_WAIT
Như trên nói cho chúng ta biết có bao nhiêu loại trạng thái kết nối và số kết nối của mỗi trạng thái đó. Chúng ta cũng có thể chạy một câu lệnh tương tự để xem trạng thái kết nối được tạo ra bởi webserver như sau:


Code:
# netstat -ant | grep 80 | awk '{print $6}' | sort | uniq -c | sort -n 

1 FIN_WAIT1
4 LISTEN
6 FIN_WAIT2
17 CLOSE_WAIT
94 ESTABLISHED
534 TIME_WAIT


Bạn có thể làm được nhiều việc phức tạp hơn bằng cách sử dụng lệnh Netstat kết hợp với các câu lệnh khác của Linux. Có thể rất hữu ích khi biết rõ một số thủ thuật của việc sử dụng Netstat, đặc biệt khi bạn đối mặt với một cuộc tấn công nhắm vào hệ thống của bạn.

What are the best linux permissions to use for website

Question:
I have a Linux web server running Apache2 that hosts several websites. Each website has its own folder in /var/www/.
/var/www/contoso.com/
/var/www/contoso.net/
/var/www/fabrikam.com/
The base directory /var/www/ is owned by root:root. Apache is running as www-data:www-data. The Fabrikam website is maintained by two developers, Alice and Bob. Both Contoso websites are maintained by one developer, Eve. All websites allow users to upload images. If a website is compromised, the impact should be as limited as possible.
I want to know the best way to set up permissions so that Apache can serve the content, the website is secure from attacks, and the developers can still make changes. One of the websites is structured like this:
/var/www/fabrikam.com
    /cache
    /modules
    /styles
    /uploads
    /index.php
How should the permissions be set on these directories and files? I read somewhere that you should never use 777 permissions on a website, but I don't understand what problems that could cause. During busy periods, the website automatically caches some pages and stores the results in the cache folder. All of the content submitted by website visitors is saved to the uploads folder.

Answer:
When deciding what permissions to use, you need to know exactly who your users are and what they need. A webserver interacts with two types of user.
Authenticated users have a user account on the server and can be provided with specific privileges. This usually includes system administrators, developers, and service accounts. They usually make changes to the system using SSH or SFTP.
Anonymous users are the visitors to your website. Although they don't have permissions to access files directly, they can request a web page and the web server acts on their behalf. You can limit the access of anonymous users by being careful about what permissions the web server process has. On many Linux distributions, Apache runs as the www-data user but it can be different. Use ps aux | grep httpd or ps aux | grep apache to see what user Apache is using on your system.

Notes on linux permissions

Linux and other POSIX-compliant systems use traditional unix permissions. There is an excellent article on Wikipedia about Filesystem permissions so I won't repeat everything here. But there are a few things you should be aware of.
The execute bit
Interpreted scripts (eg. Ruby, PHP) work just fine without the execute permission. Only binaries and shell scripts need the execute bit. In order to traverse (enter) a directory, you need to have execute permission on that directory. The webserver needs this permission to list a directory or serve any files inside of it.
Default new file permissions
When a file is created, it normally inherits the group id of whoever created it. But sometimes you want new files to inherit the group id of the folder where they are created, so you would enable the SGID bit on the parent folder.
Default permission values depend on your umask. The umask subtracts permissions from newly created files, so the common value of 022 results in files being created with 755. When collaborating with a group, it's useful to change your umask to 002 so that files you create can be modified by group members. And if you want to customize the permissions of uploaded files, you either need to change the umask for apache or run chmod after the file has been uploaded.

The problem with 777

When you chmod 777 your website, you have no security whatsoever. Any user on the system can change or delete any file in your website. But more seriously, remember that the web server acts on behalf of visitors to your website, and now the web server is able to change the same files that it's executing. If there are any programming vulnerabilities in your website, they can be exploited to deface your website, insert phishing attacks, or steal information from your server without you ever knowing.

Define the requirements

  • Developers need read/write access to files so they can update the website
  • Developers need read/write/execute on directories so they can browse around
  • Apache needs read access to files and interpreted scripts
  • Apache needs read/execute access to serveable directories
  • Apache needs read/write/execute access to directories for uploaded content

Maintained by a single user

If only one user is responsible for maintaining the site, set them as the user owner on the website directory and give the user full rwx permissions. Apache still needs access so that it can serve the files, so set www-data as the group owner and give the group r-x permissions.
chown -R eve contoso.com
chgrp -R www-data contoso.com
chmod -R 750 contoso.com
chmod g+s contoso.com
ls -l
drwxr-s--- 2 eve      www-data   4096 Feb  5 22:52 contoso.com
If you have folders that need to be writable by Apache, you can just modify the permission values for the group owner so that www-data has write access.
chmod g+w uploads
ls -l
drwxrws--- 2 eve      www-data   4096 Feb  5 22:52 uploads
The benefit of this configuration is that it becomes harder (but not impossible*) for other users on the system to snoop around, since only the user and group owners can browse your website directory. This is useful if you have secret data in your configuration files. Be careful about your umask! If you create a new file here, the permission values will probably default to 755. You can run umask 027 so that new files default to 640 (rw- r-- ---).

Maintained by a group of users

If more than one user is responsible for maintaining the site, you will need to create a group to use for assigning permissions. It's good practice to create a separate group for each website, and name the group after that website.
groupadd dev-fabrikam
usermod -a -G dev-fabrikam alice
usermod -a -G dev-fabrikam bob
In the previous example, we used the group owner to give privileges to Apache, but now that is used for the developers group. Since the user owner isn't useful to us any more, setting it to root is a simple way to ensure that no privileges are leaked. Apache still needs access, so we give read access to the rest of the world.
chown -R root fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 775 fabrikam.com
chmod g+s fabrikam.com
ls -l
drwxrwxr-x 2 root     dev-fabrikam   4096 Feb  5 22:52 fabrikam.com
If you have folders that need to be writable by Apache, you can make Apache either the user owner or the group owner. Either way, it will have all the access it needs. Personally, I prefer to make it the user owner so that the developers can still browse and modify the contents of upload folders.
chown -R www-data uploads
ls -l
drwxrwxr-x 2 www-data     dev-fabrikam   4096 Feb  5 22:52 uploads
Although this is a common approach, there is a downside. Since every other user on the system has the same privileges to your website as Apache does, it's easy for other users to browse your site and read files that may contain secret data, such as your configuration files.
You can have your cake and eat it too
This can be futher improved upon. It's perfectly legal for the owner to have less privileges than the group, so instead of wasting the user owner by assigning it to root, we can make Apache the user owner on the directories and files in your website. This is a reversal of the single maintainer scenario, but it works equally well.
chown -R www-data fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 570 fabrikam.com
chmod g+s fabrikam.com
ls -l
dr-xrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com
If you have folders that need to be writable by Apache, you can just modify the permission values for the user owner so that www-data has write access.
chmod u+w uploads
ls -l
drwxrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com
One thing to be careful about with this solution is that the user owner of new files will match the creator instead of being set to www-data. So any new files you create won't be readable by Apache until you chown them.

*Apache privilege separation

I mentioned earlier that it's actually possible for other users to snoop around your website no matter what kind of privileges you're using. By default, all Apache processes run as the same www-data user, so any Apache process can read files from all other websites configured on the same server, and sometimes even make changes. Any user who can get Apache to run a script can gain the same access that Apache itself has.
To combat this problem, there are various approaches to privilege separation in Apache. However, each approach comes with various performance and security drawbacks. In my opinion, any site with higher security requirements should be run on a dedicated server instead of using VirtualHosts on a shared server.

Additional considerations

I didn't mention it before, but it's usually a bad practice to have developers editing the website directly. For larger sites, you're much better off having some kind of release system that updates the webserver from the contents of a version control system. The single maintainer approach is probably ideal, but instead of a person you have automated software.
If your website allows uploads that don't need to be served out, those uploads should be stored somewhere outside the web root. Otherwise, you might find that people are downloading files that were intended to be secret. For example, if you allow students to submit assignments, they should be saved into a directory that isn't served by Apache. This is also a good approach for configuration files that contain secrets.
For a website with more complex requirements, you may want to look into the use of Access Control Lists. These enable much more sophisticated control of privileges.
If your website has complex requirements, you may want to write a script that sets up all of the permissions. Test it thoroughly, then keep it safe. It could be worth its weight in gold if you ever find yourself needing to rebuild your website for some reason.


Hướng dẫn Chmod an toàn cho website

DigiStar đề nghị CHMOD như sau để bảo vệ an toàn cho website tại host của DigiStar:

1) CHMOD thư mục Public_html thành 710 thay vì mặc định là 750 việc này sẽ giúp bạn bảo vệ được cấu trúc Website của mình

2) CHMOD File là 404 và nhớ rằng đừng bao giờ để là 666 nếu có việc cần 666 thì bạn CHMOD tạm để sử dụng lúc đó, sau đó hãyCHMOD lại ngay.

3) Riêng với file chứa thông tin kết nối database, CHMOD thành 400 (sử dụng chức năng "File Manager" trong cPanel để CHMOD400) .Ví dụ : config.php, configuration.php , .v.v.

4) CHMOD thư mục là 701 thay vì 755 như mặc định thường dùng. Với thư mục cần ghi như images, upload ... bạn cần CHMODthành 755 và tạo file tên ".htaccess" với nội dung như sau vào ngay thư mục này :
-----------------------------------------------------------------------------
<Files ~ "^.*\.(php|cgi|pl|php3|php4|php5|php6|phtml|shtml)"> Order allow,deny 
Deny from all </Files >

.htaccess rewrite tips

.htaccess rewrite tips

#1
Be aware that mod_rewrite (RewriteRule, RewriteBase, and RewriteCond) code is executed for each and every HTTP request that accesses a file in or below the directory where the code resides, so it’s always good to limit the code to certain circumstances if readily identifiable.
For example, to limit the next 5 RewriteRules to only be applied to .html and .php files, you can use the following code, which tests if the url does not end in .html or .php and if it doesn’t, it will skip the next 5 RewriteRules.
Code:
RewriteRule !\.(html|php)$ - [S=5]
RewriteRule ^.*-(vf12|vf13|vf5|vf35|vf1|vf10|vf33|vf8).+$ - [S=1]
.htaccess rewrite examples should begin with:

Code:
Options +FollowSymLinks
 
RewriteEngine On
RewriteBase /
Require the www

Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.askapache\.com$ [NC]
RewriteRule ^(.*)$ http://www.askapache.com/$1 [R=301,L]
Loop Stopping Code

Sometimes your rewrites cause infinite loops, stop it with one of these rewrite code snippets.
Code:
RewriteCond %{REQUEST_URI} ^/(stats/|missing\.html|failed_auth\.html|error/).* [NC]
RewriteRule .* - [L]
 
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
Cache-Friendly File Names

This is probably my favorite, and I use it on every site I work on. It allows me to update my javascript and css files in my visitors cache’s simply by naming them differently in the html, on the server they stay the same name. This rewrites all files for /zap/j/anything-anynumber.js to /zap/j/anything.js and /zap/c/anything-anynumber.css to /zap/c/anything.css
Code:
RewriteRule ^zap/(j|c)/([a-z]+)-([0-9]+)\.(js|css)$ /zap/$1/$2.$4 [L]
SEO friendly link for non-flash browsers

When you use flash on your site and you properly supply a link to download flash that shows up for non-flash aware browsers, it is nice to use a shortcut to keep your code clean and your external links to a minimum. This code allows me to link to site.com/getflash/ for non-flash aware browsers.
Code:
RewriteRule ^getflash/?$ http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash [NC,L,R=307]
Removing the Query_String

On many sites, the page will be displayed for both page.html and page.html?anything=anything, which hurts your SEO with duplicate content. An easy way to fix this issue is to redirect external requests containing a query string to the same uri without the query_string.
Code:
RewriteCond %{THE_REQUEST} ^GET\ /.*\;.*\ HTTP/
RewriteCond %{QUERY_STRING} !^$
RewriteRule .* http://www.askapache.com%{REQUEST_URI}? [R=301,L]
Sending requests to a php script

This .htaccess rewrite example invisibly rewrites requests for all Adobe pdf files to be handled by /cgi-bin/pdf-script.php
Code:
RewriteRule ^(.+)\.pdf$  /cgi-bin/pdf-script.php?file=$1.pdf [L,NC,QSA]
Setting the language variable based on Client

For sites using multiviews or with multiple language capabilities, it is nice to be able to send the correct language automatically based on the clients preferred language.
Code:
RewriteCond %{HTTP:Accept-Language} ^.*(de|es|fr|it|ja|ru|en).*$ [NC]
RewriteRule ^(.*)$ - [env=prefer-language:%1]
Deny Access To Everyone Except PHP fopen

This allows access to all files by php fopen, but denies anyone else.
Code:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^.+$ [NC]
RewriteRule .* - [F,L]
If you are looking for ways to block or deny specific requests/visitors, then you should definately read Blacklist with mod_rewrite. I give it a 10/10
Deny access to anything in a subfolder except php fopen

This can be very handy if you want to serve media files or special downloads but only through a php proxy script.
Code:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+)/.*\ HTTP [NC]
RewriteRule .* - [F,L]
Require no www

Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^askapache\.com$ [NC]
RewriteRule ^(.*)$ http://askapache.com/$1 [R=301,L]
Check for a key in QUERY_STRING

Uses a RewriteCond Directive to check QUERY_STRING for passkey, if it doesn’t find it it redirects all requests for anything in the /logged-in/ directory to the /login.php script.
Code:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !passkey
RewriteRule ^/logged-in/(.*)$ /login.php [L]
Removes the QUERY_STRING from the URL

If the QUERY_STRING has any value at all besides blank than the?at the end of /login.php? tells mod_rewrite to remove the QUERY_STRING from login.php and redirect.
Code:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} .
RewriteRule ^login.php /login.php? [L]
Fix for infinite loops

An error message related to this isRequest exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.or you may seeRequest exceeded the limit,probable configuration error,Use 'LogLevel debug' to get a backtrace, orUse 'LimitInternalRecursion' to increase the limit if necessary
Code:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
External Redirect .php files to .html files (SEO friendly)

Code:
RewriteRule ^(.*)\.php$ /$1.html [R=301,L]
Internal Redirect .php files to .html files (SEO friendly)

Redirects all files that end in .html to be served from filename.php so it looks like all your pages are .html but really they are .php
Code:
RewriteRule ^(.*)\.html$ $1.php [R=301,L]
block access to files during certain hours of the day

Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# If the hour is 16 (4 PM) Then deny all access
RewriteCond %{TIME_HOUR} ^16$
RewriteRule ^.*$ - [F,L]
Rewrite underscores to hyphens for SEO URL

Converts all underscores “_” in urls to hyphens “-” for SEO benefits… See the full article for more info.
Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
 
RewriteRule !\.(html|php)$ - [S=4]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5 [E=uscor:Yes]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4 [E=uscor:Yes]
RewriteRule ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3 [E=uscor:Yes]
RewriteRule ^([^_]*)_(.*)$ $1-$2 [E=uscor:Yes]
 
RewriteCond %{ENV:uscor} ^Yes$
RewriteRule (.*) http://d.com/$1 [R=301,L]
Require the www without hardcoding

Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$     [NC]
RewriteRule ^/(.*)$ http://%1/$1 [R=301,L]
Require no subdomain

Code:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} \.([^\.]+\.[^\.0-9]+)$
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
Redirecting Wordpress Feeds to Feedburner

Full article:Redirecting Wordpress Feeds to Feedburner
Code:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/feed\.gif$
RewriteRule .* - [L]
 
RewriteCond %{HTTP_USER_AGENT} !^.*(FeedBurner|FeedValidator) [NC]
RewriteRule ^feed/?.*$ http://feeds.feedburner.com/apache/htaccess [L,R=302]
 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Only allow GET and PUT Request Methods

Article: Request Methods
Code:
 
 
 

Code:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !^(GET|PUT)
RewriteRule .* - [F]
Prevent Files image/file hotlinking and bandwidth stealing

Code:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?askapache.com/.*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ /feed/ [R=302,L]
Stop browser prefetching

Code:
RewriteEngine On
SetEnvIfNoCase X-Forwarded-For .+ proxy=yes
SetEnvIfNoCase X-moz prefetch no_access=yes
 
# block pre-fetch requests with X-moz headers
RewriteCond %{ENV:no_access} yes
RewriteRule .* - [F,L]