dvolob
By:
dvolob

IP visitor comments is exactly like my IP droplet. So I can not cut off the spammers by their IP

January 12, 2017 1.3k views
Email WordPress Networking DigitalOcean CentOS

I have site on wordpress, and IP visitor comments is exactly like my IP droplet. So I can not cut off the spammers by their IP. How to make that when someone write a comment on the website, admin panel recorded the actual visitor's IP?

7 Answers

@dvolob

Ok, here's what we're going to do. First, deploy a Droplet using Ubuntu 16.10 64bit, preferably a 1GB or 2GB instance. Since we're running NGINX, PHP-FPM, and MariaDB plus the fact that you're hosting multiple WordPress installations, we need more resources than would be available on an instance w/ only 512MB.

Once the Droplet is setup, login as root.

Installing NGINX, PHP 7.1.x + PHP-FPM, and MariaDB

Copy + Paste the command from here to the CLI.

You'll see a dialog box pop up and ask "A new version of /boot/grub/menu.lst is available, but the version installed currently has been locally modified." -- simply hit enter (which selects "keep the local version currently installed").

What the above command will do seems complex, due to size, but what it specifically does is:

1). Sync current packages against Ubuntu's repositories.
2). Upgrade all existing packages to their latest versions.
3). Install the build environment needed for NGINX.
4). Install a new PPA so we can use PHP 7.1.x instead of 7.x.
5). Install the most used PHP packages, including PHP-FPM.
6). Download OpenSSL, PCRE, and ZLIB to compile NGINX.
7). Compile NGINX from source.
8). Remove files that we don't need.
9). Install MariaDB

Once NGINX has finished compiling, it'll begin installing MariaDB.

Securing MariaDB

Once MariaDB is finished up, we'll run one more command to wrap up our software installation and to remove un-needed data from MySQL. Simply copy & paste the following command and hit enter.

mysql_secure_installation

In order, do the following:

1). Enter Current Root Password -- Hit Enter (one hasn't been set yet)
2). Set Root Password? -- Type y, hit enter, and set a secure password.
3). Remove Anonymous Users? -- Type y and hit enter.
4). Disallow root Login Remotely? -- Type y and hit enter.
5). Remove test database and access to it? -- Type y and hit enter.
6). Reload privilege tables now? -- Type y and hit enter.

We've now successfully install NGINX from source, PHP 7.1.x + PHP-FPM, and MariaDB.

Configuring NGINX

Now, to get NGINX working the way we want, we need to modify a few files and create a few more directories. To get the directories created, we'll run:

sudo mkdir -p /etc/nginx/sites \
&& sudo mkdir -p /etc/nginx/config/php

The above are simply storage directories for our websites and PHP configuration.

Now we'll delete the current NGINX configuration file and create a new one with this configuration. Simply copy everything there and paste it in to the new nginx.conf file that we create with the below command.

sudo rm -rf /etc/nginx/config/nginx.conf \
&& sudo nano /etc/nginx/config/nginx.conf

Now let's create our first website server block. We'll store our website server blocks in the sites directory we created above, so:

sudo nano /etc/nginx/sites/example.com.conf

With that file open, we'll paste in:

server {
    listen                                          80;
    server_name                                     yourdomain.com www.yourdomain.com;
    root                                            /home/yourdomain/htdocs/public;
    index                                           index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    include                                         /etc/nginx/config/php/php-fpm.conf;
}

Now we need to create our php-fpm.conf file which is required by the above server block. So like the above, we'll create that file in our newly created php directory.

sudo nano /etc/nginx/config/php/php-fpm.conf

and paste in the contents from this gist.

NGINX is now configured and can be started by running:

nginx

When changes are made, you can reload those changes using:

nginx -s reload

Configuring PHP-FPM

The last thing we need to do is change the way PHP-FPM listens for connections. By default, it uses sockets. This is fine, TCP is most ideal for a multi-site environment.

So we need to open the existing file:

sudo nano /etc/php/7.1/fpm/pool.d/www.conf

and change:

listen = /run/php/php7.1-fpm.sock

to

listen = 127.0.0.1:9000

Then restart PHP-FPM:

sudo service php7.1-fpm restart

What Do I Do Now?

The server block we just created needs to be modified to match a real domain and you need to set a real root path so NGINX knows where to direct requests. Once this is done, you can create an index.php file in the root directory and test the configuration out.

From there, you can create a MySQL Database + User using the MySQL CLI or Adminer/phpMyAdmin (web-based interface) and test a WordPress installation.

How Do I Add New Sites?

You can drop new server blocks in /etc/nginx/sites/ and once set, reload NGINX to make the changes stick, i.e.

sudo nano /etc/nginx/sites/newsite.net.conf

Paste in your configuration...

nginx -s reload

Of course, create the directories for each site and make sure the root path is set for each domain.

You can in fact get a little more complex, but before we go in to creating PHP-FPM configurations for each account, I want to make sure we get this setup first!

  • @dvolob

    One thing to keep in mind here is that we're running very basic server blocks for each site we're creating. Things can get more complex, and we can go that route, though the primary goal here is dropping Apache and removing the proxying when it's not needed.

    We can add things like caching, logging, etc (which I skipped intentionally to simplify things a bit while you get the above running). I tried to automate the majority for you with the one command that you initially run, though beyond that, the rest needs to be done by hand for the time being.

    You can also automate creating new server blocks using Bash Scripting. It's relatively easy to do and once you have a working knowledge of the above, we can make things even easier.

    Let me know if you run in to any issues.

Are you using a reverse proxy? Did you check the access logs?

  • netstat -tlpn
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address Stat e PID/Program name

    tcp 0 0 0.0.0.0:993 0.0.0.0:* LIST EN 1570/dovecot
    tcp 0 0 0.0.0.0:995 0.0.0.0:* LIST EN 1570/dovecot
    tcp 0 0 0.0.0.0:3306 0.0.0.0:* LIST EN 1528/mysqld
    tcp 0 0 0.0.0.0:110 0.0.0.0:* LIST EN 1570/dovecot
    tcp 0 0 0.0.0.0:143 0.0.0.0:* LIST EN 1570/dovecot
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LIST EN 1694/nginx
    tcp 0 0 0.0.0.0:465 0.0.0.0:* LIST EN 1655/master

    tcp 0 0 0.0.0.0:22 0.0.0.0:* LIST EN 1211/sshd
    tcp 0 0 0.0.0.0:25 0.0.0.0:* LIST EN 1655/master
    tcp 0 0 127.0.0.1:953 0.0.0.0:* LIST EN 1138/named

    tcp 0 0 :::81 :::* LIST EN 1679/httpd
    tcp 0 0 :::465 :::* LIST EN 1655/master
    tcp 0 0 :::21 :::* LIST EN 1668/proftpd
    tcp 0 0 :::22 :::* LIST EN 1211/sshd
    tcp 0 0 :::25 :::* LIST EN 1655/master
    tcp 0 0 ::1:953 :::* LIST EN 1138/named

Yes, I checked the log access, and there I see that a comment has the same IP address of the site.

If the user surf on the site, the logs can see its real IP. If the user writes the comment, IP changes to droplet IP.

@dvolob

How was your Droplet setup? Did you use a one-click image or did you install all software yourself? We need to know more about how your Droplet was setup before we can help.

To me, initially, it seems like you're using a reverse proxy and that correct headers are not being sent, so when WordPress queries for the visitor IP, it's reverting to the server IP as it can't determine the real IP.

I make one-click image gentos 6 at first, and them install nginx and reverse proxy myself. I have several wordpress sites on this droplet. I use ispmanager.

that's part of my nginx.conf : (46.xx.xx.xx and mysite.com - as an example)

user nginx;
workerprocesses 1;
error
log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
defaulttype application/octet-stream;
log
format main '$remoteaddr - $remoteuser [$timelocal] "$request" '
'$status $body
bytessent "$httpreferer" '
'"$httpuseragent" "$httpxforwardedfor"';
access
log /var/log/nginx/access.log main;
sendfile on;

keepalive_timeout  65;
gzip  on;
include /etc/nginx/conf.d/*.conf;
include /usr/local/ispmgr/etc/nginx.domain;
client_max_body_size 128M;
log_format isp '$bytes_sent $request_length';
server {
    server_name isptest.mgr;
    listen 80;
    disable_symlinks if_not_owner from=$root_path;
    set $root_path /var/www/mgrtest/data/www/isptest.mgr;
    location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        root $root_path;
        access_log /var/www/nginx-logs/mgrtest isp;
        access_log /var/www/httpd-logs/isptest.mgr.access.log ;
        error_page 404 = @fallback;
    }
    location / {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location ~* ^/(webstat|awstats|webmail|myadmin|pgadmin)/ {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location @fallback {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    include /usr/local/ispmgr/etc/nginx.inc;
}
server {
    server_name mysite.com www.mysite.com;
    listen 80;
    disable_symlinks if_not_owner from=$root_path;
    set $root_path /var/www/user/data/www/mysite.com;
    location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        root $root_path;
        access_log /var/www/nginx-logs/user isp;
        access_log /var/www/httpd-logs/mysite.com.access.log ;
        error_page 404 = @fallback;
    }
    location / {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location ~* ^/(webstat|awstats|webmail|myadmin|pgadmin)/ {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location @fallback {
        proxy_pass http://46.xx.xx.xx:81;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location ^~ /webstat/ {
        auth_basic "Restricted area";
        auth_basic_user_file /var/www/user/data/etc/920135.passwd;
        try_files $uri @fallback;
    }
    include /usr/local/ispmgr/etc/nginx.inc;
}

}

  • @dvolob

    Thanks! So I see all of the proxy details, though I'm not seeing your PHP-FPM configuration (i.e. the fastcgi_params that you have set, whether it's the actual fastcgi_params file or custom).

    The issue, from what I can see, is that WordPress is relying on REMOTE_ADDR and it's never actually being set to the real IP address -- instead, it's using the proxy server IP. To fix that, we'll make one small change and test it.

    Find your fastcgi_params configuration, which should be within your PHP server block, and change what REMOTE_ADDR requests -- i.e. change it to:

    fastcgi_param REMOTE_ADDR $http_x_real_ip
    

    Now restart NGINX and test things out to see if they pulls the correct IP. If this does not work, we need to see if NGINX is compiled with --with-http_realip_module. If it's not and the above did not work, then we need to compile NGINX with that module and instead of using the above, we will make another change.

    That change would be adding:

    set_real_ip_from   IP;
    

    Where IP is equal to the IP address showing up in the comments. Compiling this module and using this line instead of modifying the fastcgi_params should allow REMOTE_ADDR to work normally.

    The downside here is that if you installed NGINX using the package manager and the packages available from the repo do not include this module, you will have to compile NGINX from source.

    • Thanks for the detailed answer !
      I'm not very well versed in Linux, and I can not solve this problem. I found that PHP-FPM is not installed, and setup it. Installing: php-fpm-5.4.45-12.el6.remi.i686

      I added to nginx.conf this block:

      location ~ \ .php $ {
      fastcgisplitpathinfo ^ (+ \ php..) $ (*.);
      root $ root
      path;
      include / etc / nginx / fastcgiparams;
      fastcgi
      pass 127.0.0.1:9000;
      fastcgiparam REMOTEADDR $ httpxrealip;
      fastcgi
      index index.php;

      }
      but these settings any *.php file on the site shows a blank page with no errors.

      Here is my file fastcgi_params:

      fastcgiparam QUERYSTRING $ querystring;
      fastcgi
      param REQUESTMETHOD $ requestmethod;
      fastcgiparam CONTENTTYPE $ contenttype;
      fastcgi
      param CONTENTLENGTH $ contentlength;

      fastcgiparam SCRIPTNAME $ fastcgiscriptname;
      fastcgiparam REQUESTURI $ requesturi;
      fastcgi
      param DOCUMENTURI $ documenturi;
      fastcgiparam DOCUMENTROOT $ documentroot;
      fastcgi
      param SERVERPROTOCOL $ serverprotocol;
      fastcgiparam REQUESTSCHEME $ scheme;
      fastcgiparam HTTPS $ https ifnotempty;
      fastcgi
      param REMOTEADDR $ httpxrealip;

      fastcgiparam GATEWAYINTERFACE CGI / 1.1;
      fastcgiparam SERVERSOFTWARE nginx / $ nginx_version;

      fastcgiparam REMOTEADDR $ remote_addr;

      fastcgiparam REMOTEPORT $ remoteport;
      fastcgi
      param SERVERADDR $ serveraddr;
      fastcgiparam SERVERPORT $ serverport;
      fastcgi
      param SERVERNAME $ servername;

      PHP only, required if PHP was built with --enable-force-cgi-redirect

      fastcgiparam REDIRECTSTATUS 200;

      and Apache's configuration

      <Directory /var/www/user/data/www/mysite.com>
      Options -Includes -ExecCGI
      phpadminvalue openbasedir "/ var / www / user / data :."
      php
      admin_flag engine on
      </ Directory>

      <VirtualHost 46.xx.xx.xx:81>
      ServerName mysite.com
      CustomLog /var/www/httpd-logs/taxi177.ru.access.log combined
      DocumentRoot /var/www/user/data/www/mysite.com
      ErrorLog /var/www/httpd-logs/mysite.com.error.log
      ServerAdmin xxxxxx@gmail.com
      ServerAlias ​​www.mysite.com
      SuexecUserGroup user user
      AddType application / x-httpd-php .php .php3 .php4 .php5 .phtml
      AddType application / x-httpd-php-source .phps
      phpadminvalue openbasedir "/ var / www / user / data :."
      php
      adminvalue sendmailpath "/ usr / sbin / sendmail -t -i -f xxxxxx@gmail.com"
      phpadminvalue uploadtmpdir "/ var / www / user / data / mod-tmp"
      phpadminvalue session.save_path "/ var / www / user / data / mod-tmp"
      </ VirtualHost>

      I'm not sure I can make recompilation NGINX with --with-httprealipmodule
      I can show you the output of commands required for the diagnosis of the current server state.
      For example,

      netstat -ntulp

      Active Internet connections (only servers)

      tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 27152/php-fpm
      tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1480/mysqld
      tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN 1522/dovecot
      tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 27063/nginx
      tcp 0 0 :::81 :::* LISTEN 27240/httpd
      .............

If this block
proxysetheader X-Forwarded-For $ proxyaddxforwardedfor;
proxysetheader X-Forwarded-Proto $ scheme;

is added to

location ~ \ .php $ {
fastcgisplitpathinfo ^ (+ \ php..) $ (*.);
root $ rootpath;
include / etc / nginx / fastcgiparams;
fastcgipass 127.0.0.1:9000;
fastcgiparam REMOTEADDR $ httpxrealip;
fastcgiindex index.php;
}

all * .php starts to work! But IP is not transmitted at all, there is an empty space in site page
where is to be output IP.

@dvolob

Is there a specific reason you're using both Apache + NGINX? I ask as unless you're familiar with both and able to administer both, you're really making things a multitude more complex than they need to be (i.e. you're making your life harder).

Would you be open to allowing me to help you simplify things? By that, I mean dropping Apache and setting up with NGINX + PHP-FM + MariaDB (a drop-in replacement for MySQL).

If so, I can provide you with a very simple way of getting it all setup and you'll only need to handle a few things afterwards.

  • Thank you ! I have no reason to use Apache, I just did, like everyone else. I'm certainly willing to simplify the configuration, if you tell me how to do it.

Have another answer? Share your knowledge.