Fixing PHP’s ‘Warning: simplexml_load_file(): I/O warning : failed to load external entity’

Today I had to re-visit a Drupal module I wrote in 2015. The module parses an external XML file which it loads using simplexml_load_file. When I opened the version of the site that lives in my local server, and visited the page that uses the module, I got the error in the title of this entry. I checked php.ini to make sure allow_url_fopen was On. It was.

Searching the web I came to a bug report in the php website. It was suggested to restart the apache server since the contents of resolv.conf may have changed after the server, and php got their DNS servers entry. This made sense to me, since I have switched networks since turning the computer on. I gave it a try, and it worked:

service httpd restart

Other info:

  • The location of php.ini in my case, running Fedora with php installed using dnf, is /var/php.ini
  • The location of resolv.conf is /etc/resolv.conf

The sources I visited:

Advertisements

So Long Online Localhost

As you may know from previous posts, I have a server at home that I use for development. I had this server online thanks to dyn.com, but today I got an unpleasant notification from one of my clients. He reported that the server was not working. This was not good news. As it turns out, I don’t know why the server stopped working. All I know is that it is taking too long to respond, which is weird because I can access it from the internal network without a problem.

I have two thoughts:

1) My ISP blocked me.
2) My server was someone hacked, and is being blocked.

The second thought is a strong one, especially considering that the last incoming connection from outside the server, as reported by the apache logs is this:

77.242.153.180 – – [04/Dec/2012:12:11:01 -0800] “\xce\x89\x8d\x85b\ro” 400 317 “-” “-“

Under other circumstances I would mask the IP with 00.000.000.000, but considering that this person was trying something malicious, why the heck would I care.

What I did after deciding to give up on trying to restore access to the server from outside the local network is this:

1) Clear the port forwarding table in the router.
2) Delete my dyn.com hostname
3) Adjust my tools so they would FTP and SSH to the server’s local IP.
4) Clear my old web domain contents to make space to upload projects there so that clients can access them.
5) Add a new line to the host file:
192.168.0.14 dev
This allows me to use dev/projectname/ in my machine rather than typing the ip of the server.

It will be a pain having to upload project updates at the end of every day, but for now that is what I will have to do. I’m considering a VPS on Hostgator, but I need to look a bit more into that option. The one thing that I regret for now is not having the “luxury” of going to the cafe and work from there, since my server is now unreachable from outside the local network.

I am also considering a full reinstall on the server to 1) Make sure that if anyone did hack and messed around the server it will go back to normal, and 2) To maybe change distro, Ubuntu doesn’t make me happy anymore. This time I might compile apache and php again, rather than installing some pre-compiled version.

Ideally, I would like to have a machine online again, even if I have to pay for that, but it must allow me to use it just as if it were right next to me. It must allow me full control over it, even if it is a VM. By that I mean, I should be able to install, and uninstall any software that I need. Access should be over SSH, at the least. Do you know any good service that provides this? Should I go with Hostgator VPS?

Setting Up mod_status on Apache

Via hacker news I found an interesting article that talked about popular sites that leave the server status page visible to everybody. If you would like to read the article, you can find it at http://blog.sucuri.net/2012/10/popular-sites-with-apache-server-status-enabled.html. This got me interested on setting up mod_status on my server. Now, I want to teach you how you can set up mod_status on your server and make sure only you can access it. The first thing you need to do is make sure mod_status is enabled. Open the terminal and type:


a2enmod status

If you need admin permissions, use sudo in front of everything else.

Once it is enabled, we need to set a handler for it. Open you apache2.conf file, or httpd.conf file depending on which you use. In my case, running ubuntu on my server, I use apache2.conf, located at /etc/apache2/apache2.conf. Since this file is most likely owned by the server, you need to use sudo:


sudo vim /etc/apache2/apache2.conf

Now you need to add this to that file:


<Location /server-status>
SetHandler server-status

Order Deny,Allow
Deny from all
Allow from .example.com
</Location>

What this is doing is setting a Location handler for the /server-status path. The handler is the server-status module. Then we proceed to deny access to it for all, and allow access only from example.com and any subdomine of it. You will need to change that part to allow access only for the desired domains. In my case, I access my server from the internal network, so I allowed access only from the ip of the machine that I use to access the server.

Let me explain a bit more that part. I have a server running, which can be accessed via its url. However, in my hosts file I’ve set up a rule to point the server’s url to the server’s internal ip. This is important because then my computer accesses the server from its internal ip, which is 192.168.0.10. The server’s internal ip is 192.168.0.14. Now, what I need to do is allow access to the /server-status page only to connections coming from 192.168.0.10, which is my computer’s ip. So the part I added to the apache2.conf file looks like this:


<Location /server-status>
SetHandler server-status

Order Deny,Allow
Deny from all
Allow from 192.168.0.10
</Location>

Now I can access the /server-status information only from my computer. Not even the server itself has access to it.

You can change the Location part to something else like Location /status or Location /pirates, and then you would access the server info via that path, but I found that doing that allows the server to access the information via /server-status even if we specify access only for connections coming from a different ip than the server’s. My suggestion would be to leave the Location part as is.

To learn more about the mod_status module, check out the apache docs page: http://httpd.apache.org/docs/2.2/mod/mod_status.html

Fixing 500 OOPS: vsftpd: refusing to run with writable root inside chroot() on vsftpd

I was informed last night by one of my clients that he could not log into the server via ftp. I was surprised, and immediately blamed the new update (Ubuntu 12.04 LTS). This new update, updates vsftpd to 2.3.5, which tries now to be more secure by not allowing login with writable root directory. This does not affect my user, but if you remember from when we set up the new user, we added a list of users who would chroot() to their home directories. This directories are writable, so vsftpd is not allowing them to login.

The solution, as simple as it sounds, is to revoke writable permissions to this directories. Depending on how you have your system set up, this might not be the best solution for you. In my case it made no much difference. I have the user’s home directory set as wp-content, a directory inside any wordpress installation. My client only needs to be able to upload plugins, so giving him access to only that part of the server seemed like a good idea. The only thing I had to make sure of, is that he were not able to write to that file, so vsftpd would not complain. I did this:

chmod a-w /path/to/wp-content/
chmod u+w /path/to/wp-content/

First we remove write permissions for everybody, then add them only to the owner of the file, which in this case is not my client, but me. If the user you are trying to fix is the owner of the directory, don’t do the second line.

This fixes the problem, and you don’t even have to restart vsftpd.

Some references:
http://askubuntu.com/questions/128180/vsftpd-stopped-working-after-update

http://www.benscobie.com/fixing-500-oops-vsftpd-refusing-to-run-with-writable-root-inside-chroot/

I am a curious person, and this time I got curious about chroot, if you are curious too, read:
http://wiki.linuxquestions.org/wiki/Chroot
http://everyjoe.com/technology/explain-what-is-chroot/
https://help.ubuntu.com/community/BasicChroot
https://en.wikipedia.org/wiki/Chroot

Set Up Postfix to Solve Blocked Port 25 Issue, and Send Emails from Localhost.

Or Stop Complaining, and Solve the Problem

Jump right to the answer without reading my badly narrated experience

I wrote a few hours ago about AT&T blocking port 25, and why that matters. For a moment, I decided to just write that post and wait until morning to call AT&T, but then I asked about the issue on Super User, and the answer I got made me curious about this issue, so I went back to it. It paid off. I was finally able to fix the problem. It took me already about 7 hours going on and off on this issue, but I’ve learned some new stuff, which is great. Now I just need to hurry up and start working on the project that required localhost to be able to send emails.

It is actually not that difficult to solve this problem, but it can be if you don’t know how to. I hope I can save you many hours with this post.

Based on the idea I got from the answer on Super User, I decided to try to use a different port. I had tried before using an smtp server to relay the emails. I tried with my ISP’s SMTP server (outbound.att.net according to their website). But it would not work. All I got was a connection timeout. This is because I was attempting to connect on port 25, which is blocked.

So, I started playing with the port number. First I followed the steps outlined on this website: http://www.linuxmail.info/postfix-change-port/ but that didn’t help. And to be honest I’m not quite sure what it is they are doing in that post, so I just decided to put everything back. I will copy and paste the post, just to be sure to keep the content in case that site goes offline. We never know:

By default, Postfix listens on the SMTP port number 25. Some ISPs block this port number so you may wish to provide an alternate port number to listen to or change it altogether.

Edit master.cf

1. Edit the file /etc/postfix/master.cf and find the line below. You can comment the line below by adding # in front of the line to disable SMTP port 25.

smtp inet n – n – – smtpd

Next, add this line

25000 inet n – n – – smtpd

Replace 25000 with your preferred alternate port number.

Restart the Postfix service or the MailScanner service if you have integrated MailScanner into Postfix.

If you have enabled the firewall, you need to configure the firewall to allow traffic on the new port number.

Test Postfix by connecting on the new port number. Use the terminal command telnet localhost [port] instead of telnet localhost smtp to test your new port number.

Since this did not help, I was back to square 1. Next I did some stupid things like trying to set the relay on the main.cf file (/etc/postfix/main.cf) to localdomain, and localhost. This of course were just plain stupid ideas, but I didn’t know what else to do. I got the idea from reading the section “What delivery method: direct or indirect” on the postfix configuration manual, which by the way is very interesting.

Well, none of that helped. So I decided to try with my online server’s smtp server. I got this value because at some point I set an account on Thunderbird to see if it had any problem sending emails. Thunderbird automatically detected my server’s smtp server, and that is the value I used, but I’m sure that if you have a hosting provider, and they offer email service with your own domain name, you should have your server’s smtp server address. In my case it is smtp.mydomain.com

Once again, it would not work because I was using the wrong port number. So I searched for information on how to change the port number. However, I was confused, and ignorant, so I searched for how to change the port number on sendmail, since the last instructions on post number changing hadn’t helped at all. I found results like these:
http://www.linuxforums.org/forum/servers/23275-sendmail-how-do-i-change-ports-being-used.html

http://lists.freebsd.org/pipermail/freebsd-questions/2004-June/048640.html

http://www.linuxquestions.org/questions/linux-server-73/how-can-i-change-my-sendmail-port-number-in-centos-5-4-a-895450/

The problem is that sendmail is a different program, so none of them were of help. If I mention them it is just because I like to read this kind of posts later when I have a better understanding of the subject, and laugh at my own ignorance 😉

At the moment, I did not know that I was seeing documentation, and answers for another program, so I was looking for sendmail.cf on my computer. This turned out to be a good thing, because it took me to the place where I found the answer to the problem.

Trying to find sendmail.cf, I got to this forum post:
http://ubuntuforums.org/showthread.php?p=11780787#post11780787
Which not only has good information, but also links to:

http://www.thheuer.com/2012/03/smtp-postfix-server-setup-for-your-home-development/
Where I found the answer to the problem. I must admit that before trying this out, I continued wasting time trying some other stupid things, like the aforementioned about localdomain as relyhost. Why? Pure lazines. I didn’t want to follow through the steps outlined on that post. Shame on me!

Also, at some point I considered using some kind of public SMTP server, or getting one from dyn.com. Searching for public SMTP servers, I got to this websites, that have information that I considered to be useful:
http://www.werockyourweb.com/list-outgoing-smtp-mail-servers <- A list of outgoing SMTP servers
http://publicsmtpserver.com/ <- Info about why we need public SMTP servers.
I considered using some other SMTP server quite early in this process, but it was just an idea I had, and not an appealing one.

Anyway, if you didn't read the post about how to solve the problem, this is basically what you need to do:

Firs you need an SMTP server, could be your ISP’s SMTP server. You will use it to relay your email. IF it requires authentication, you will need your user name and password.

First you need to create a file on /etc/postfix/. Call this file relay_passwd. I assume you could call it anything you want, but relay_passwd is a good name. On this file put the login information:

smtp.server.com USER:PASSWORD

you need to change smtp.server.com for your smtp server, USER for your username, and PASSWORD for your password.

Once you’ve created this file, you need to run

postmap /etc/postfix/relay_passwd

on the command line.
This will create a new file, with .db extension. If you forget this step, like I did, you will get an error.

bad command startup -- throttling postfix

As this page explains: http://www.devheads.net/server/postfix/user/bad-command-startup-throttling.htm The real error is a couple of lines before, and it will say that the file relay_passwd.db is missing. IF you get this error, chances are you forgot to run the postmap command.

Once you have the .db file, you need to set the following on your /etc/postfix/main.cf file:

relayhost = [smtp.domain.com]  # this is the important line!
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_passwd
smtp_sasl_security_options = 

Don’t overlook that last option. When I first made this changes, I decided not to add that line because it has no value. As it turns out, that line is overwriting the default value. If your smtp server expect plain text for authentication, you need that line, as explained on https://discussions.apple.com/thread/1930273?start=0&tstart=0 If you don’t add that line, but you need it, you will get an error saying “SASL authentication failed; cannot authenticate to server smtp.server.com[serverip]: no mechanism available”. If you get this error, then you need that line.

Finally, restart your postfix:

sudo /etc/init.d/postfix restart

And that’s it. Now your server should be able to send email.

It took me a long time, a lot of trial and error, and a lot of reading on the mail log file (/var/log/mail.log) to fix this issue, and although I’m tired, and sleepy, I feel quite stisfied that I was able to solve it. But I hope I can avoid you going through the same process by writing this entry on my blog. Good luck, and happy coding!

Mr. AT&T, Could You Stop Blocking Port 25?

Well, I just lost more than 4 hours trying to get my localhost to work. Amazing how much time we can waste on simple tasks. Especially, when we are stubborn.

A while back I showed you how to set your local server to send out email. That is really a simple task, but it can become an impossible task if your ISP decides to block port 25, which AT&T does. To some extent, I’m contempt with the internet service I get for aforementioned ISP, but today I just want to kill them.

Since they have decided to block port 25, I cannot send email from my locally installed wordpress instances. Is this important? Not most of the time, but when my project requires emails to be sent, then it becomes a problem. Sometimes you can just do little tricks like printing out the content of the email, and that is OK. After all, you are on development phase, and you know to disable the line that prints out the text when your project goes live. But when the whole project depends on emails being sent, and those emails have attachments, then that is a different story.

Fortunately, there is an open network that I can connect to. This seems not to block port 25, so I was able to determine that the settings on my configuration file for postfix are OK, and that it works. I was able to send emails to a gmail account. Not to hotmail account since, according to the mail logs, they don’t seem to accept incoming email from dynamic IPs.

For now, I’ve decided to wait until tomorrow and call my ISP help desk, and see what I can do about that.

If you wish to read more on the subject, I suggest the following:

https://help.ubuntu.com/8.04/serverguide/C/postfix.html
http://serverfault.com/questions/142098/how-to-configure-my-local-server-to-send-email
https://imbuzu.wordpress.com/2010/10/24/mandando-mails-desde-localhost-apache-server-ubuntu/ (spanish)
http://www.linuxtopia.org/ProblemSolutions/smtp_port_25_timeout.html
http://lists.freebsd.org/pipermail/freebsd-questions/2004-January/033078.html
http://earthnet.net/support/email/email_port25.htm
http://stackoverflow.com/questions/328914/how-to-check-if-my-isp-blocks-port-25

There is also this nice website to find out if a port is open on your network. Although, that is for incoming connections, rather than outgoing:
http://www.canyouseeme.org/

Adding New FTP Users on Localhost (vsftpd)

A while back I wrote about how to install an FTP server for your localhost. It is a very simple thing to do, and it is really useful. You can, for example, share files with other people via FTP, or access your files from any computer that has internet connection. Even with your phone. SSH is always better, of course, because it is a remote shell, but FTP is sometimes enough.

The FTP server we are using is vsftpd, and basically, any user that is registered on the machine can log in via FTP. This could be a problems. For example, I was required to give one of my clients access to my local server via FTP. I wanted to restrict the directories he has access to, but if you don’t set vsftpd properly, you can end up giving somebody full access to your machine. This is a real problem.

So, how do you add new users to vsftp properly? You need to change the configuration file for vsftpd.

First you need to create a new user, if you don’t have it yet. In my case I didn’t. Just create a user as you would normally do. On Ubuntu 11.10, just go to the User button on the top right corner, and choose the Online Accounts… option. This will open up a window, and there you can choose to create a new user.

Once your new user has been created, a home folder for that user is created too. In my case, I wanted to give this new user access to another part of the computer, so I just changed the user’s default home folder to the path of the directory I wanted to give the user access to:

usermod -d /path/to/new/homedir/ username

Just input that on the command line, and press enter. Remember to change the path, and the username to the correct values.

Once we have the user set, it is time to modify the vsftpd configuration file.
Just open the file, which should be located at /etc/vsftpd.conf

Look for:

chroot_list_file=/etc/vsftpd.chroot_list
chroot_list_enable=YES

and set them as shown above. You might need to open the config file with root privileges. In that case sudo will be your friend, or gksudo if you are using a graphical text editor.

This two settings pretty much let vsftpd know that you will be using a list to specify which users will chroot() to their home directory. This means that for those users the root or topmost directory will be their home directory, thus preventing them from having access to any other part of your computer.

Since you are already editing the config file, you might want to set the local_umask directive to 022

local_umask=022

By default vsftpd has a default umask of 077, which means that when a user uploads a file to the server, the file gets set with permission 700, and this makes it pretty much inaccessible, depending on your server configuration.

Save your changes, and create a new file on /etc/ and call it vsftpd.chroot_list

sudo touch /etc/vsftpd.chroot_list

Open this file and add the name of the users you want to chroot() to their home directory.

Restart vsftpd

sudo restart vsftdp

And you are all set. Before giving your user their username and password, you might want to check that in fact everything went well, and they cannot access anything beyond their home directory.

Something I learned is that you should not put a comment after any of the directives on the config file. It will cause and error and you might have to reconfigure vsftpd.

Some articles that were useful are listed here for future reference:
http://linux-hacks.blogspot.com/2008/09/adding-new-users-to-vsftpd.html
http://askubuntu.com/questions/73323/how-to-setup-vsftpd-for-multiple-users-including-adding-specific-directories
http://www.spiration.co.uk/post/1294/Unix-/-Linux-change-a-user%27s-home-directory—usermod
http://ubuntuforums.org/showthread.php?p=9773525
http://ubuntuforums.org/showthread.php?t=1436738

Installing an FTP Server on Ubuntu

I had been postponing this task for some time now thinking that it would be time consuming. However, it is actually pretty simple.

Since I did not know of any FTP server, I did a quick search:

aptitude search ftp

I got a bunch of results but I decided to try vsftp after seeing somewhere that it was the default daemon for linux. So I just ran

sudo apt-get install vsftpd

And that is it. I’m done.

I tested using fireftp on my other machine and it connects via ftp to the server. Now, this setup is just for an in-house server. If you plan on opening your ftp server to the outside world, you should read more about the matter, and read the man pages for vsftpd.

Also take a look at the configuration file located on /etc/vsftpd.conf

Some links that might be useful:

http://blog.dhavalparikh.co.in/2009/11/setting-up-ftp-or-sftp-server-using-vsftpd-on-ubuntu/
http://ubuntuforums.org/showthread.php?t=91887
https://duckduckgo.com/?q=ftp+server+linux
This last link is just a search results list. One one of those result previews is where I read that vsftpd is the default ftp daemon on linux, but the link, which points to http://www.scribd.com/doc/26706992/FTP-Server-in-Linux is unreadable.

Bits About Localhosts

I was playing a bit today with my local host. Basically I wanted to make it available over the net. This task is somewhat complicated or not depending on your network. For example, a few months ago, when I was using a different ISP and a different router, if I wanted to expose my local server to the whole world over the net I just had to rout http requests to my computer’s internal IP, that is usually something like 192.168.1.1 It was all good, but now I’m having trouble doing the same. I’ve set the router’s settings so that it should be sending all http connections to my computer to handle them, but it just doesn’t do it. At most I can access my local server from within my network. That is, my devices currently connected to the router.

To do this, I need only enter the ip address of my computer in the address bar of the browser. For example, in my tablet I enter 192.168.1.67, which is my laptop’s assigned ip address. This works well, and I am able to see the index page of my apache server’s home directory. So, I wanted to do the same with node, because I was also playing with node.

I created a small and useless server with node, and set it to listen on port 1337. Then, on the tablet I enter the address 192.168.1.67:1337, and nothing happens. The tablet cannot establish a connection with node. But on the computer, if I enter localhost:1337, everything works great. So I ask myself what could be the problem here.

I take another look at my node.js server, and find this line:

server.listen(1337, “127.0.0.1”);

And that makes me think. It is obvious that the server is listening to 127.0.0.1, but so is apache, and there is no problem with apache. Then it occurs to me that everything might work if I set node.js to listen to the ip assigned to the computer by the router rather than to 127.0.0.1, so I change that line to

server.listen(1337, “192.168.1.67”);

refresh the browser on the tablet, and it works. So what is the problem here?
Clearly, the problem is that the server is bound to the wrong ip address. So, how come apache works with no problem? Well, that is because apache listens to all addresses in the machine by default. So when I access 192.168.1.67, apache is listening to that address and that is why it serves the page without any problem. If we want to achieve the same result in node.js, we need to leave that second parameter empty for the listen method:

server.listen(1337);

This solves the problem, now I can access the node.js server from the tablet using my computer’s ip address and from the computer itself using localhost, because seriously, it is far more comfortable than writing an ip address.

The problem with exposing the server to the outside world is still there, but for now I’m OK with what I learned.

Actualizando php y resolviendo errores con mysql.

Otra vez se llegó la hora de actualizar php. No tanto por que me preocupara que estuviera un poco atrasado, sino por que vanilla forms requiere que el driver pdo de mysql esté funcionando y en mi caso no lo estaba. Ya que para habilitado dicho driver era necesario volver a compilar php, pensé que sería buena idea actualizar php de una buena vez.

Lo primero que hice fue ir al sitio de php y descargar la versión mas nueva (5.3.6), descomprimir el archivo en mi Escritorio y proseguir con la configuración. Para ello hay que cambiar al directorio de php. En mi caso:

cd ~/Desktop/php-5.3.6
./configure [opciones de configuración]

Todo estaba bien hasta que la configuración fallo debido a un error:

Cannot find MySQL header files under yes. Note that the MySQL client library is not bundlCannot find MySQL header files under yes. Note that the MySQL client library is not bundled anymore!ed anymore!

Una búsqueda rápida rebeló que la solución era:

sudo apt-get install libmysqlclient-dev

fuente: http://ubuntuforums.org/showthread.php?t=637973

Una vez hecho eso, todo funcionó de maravilla. Justo ahora make está corriendo y parece que todo está bien.

Si estás pensando en actualizar php, asegúrate de correr phpinfo() primero para que puedas ver tu configuración anterior.Una vez corres la función phpinfo(), en la tabla que se genera, una de las primeras entradas es la configuración con la que la instalación de php que está corriendo fue compilada. Si quieres agregar nuevos módulos, como en mi caso, solo agrégalos junto con tu configuración anterior y de ese modo tu instalación estará como antes, más los nuevos módulos.