Category: Website Hosting

  • Security from Bad User Agents

    One way to protect your site is blocking bad “User Agents”.

    A user agent is the way your browser identifies itself to your server. Your server could use this to send different versions of your site to the browser; for example, not sending images to a Lynx browser that only displays text, or to a browser that is a screen reader for blind or low-vision people. My Firefox browser has this user agent:

    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0

    Search engines also make requests of your server and identify themselves with a user agent, as do hacker bots.

    The User Agent can be changed. Some browsers pretend to be a version of Internet Explorer. Some hacker bots pretend to be any major browser they like, switching for different requests. Some pretend to be Google’s search engine bot.

    Web site developers will use browser plugins to send a different user agent string, so they can test what their web site sends to people with other browsers. (I’m using the Firefox “User Agent Overrider” plugin to change my browser’s user agent; on my server I detect user agent, which lets me know the browser type and version, operating system, whether it is a mobile device, and more, using a PHP script from http://techpatterns.com/downloads/php_browser_detection.php which I think is much nicer than using javascript since I only send to the browser the best HTML/ CSS for it.

    So the User Agent isn’t a good field to check for security. There are other fields that bad bots can’t fake, for example bad words/phrases in the URL they are looking for on your site.

    But checking the user agent is good for blocking nuisances that waste your site resources.

    How Do You Block a User Agent

    Almost all shared hosting accounts are on Apache servers.ย  Microsoft IIS is much harder for most people to use, so I’ll give Apache .htaccess examples.

    The “Better WP Security” plugin for WordPress has a good-sized list of bad User Agents that it can add to your site’s list.

    Here’s some of their code for blocking user agents (all the other examples I’ve seen use the exact same approach):

    RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^EmailCollector [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [NC,OR]

    The ^ means “at the start” of the User Agent, the [NC,OR] says not case sensitive and any one or the other will match.

    Here’s how I do the same thing, but allowing me to set exceptions to the security rule, and to log what specifically triggered the rule:

    SetEnvIfNoCase User-Agent (eirgrabber|emailcollector|emailsiphon|emailwolf) badUserAgent=$1

    For User-Agent values that have multiple values (the | separates them) and that contain special characters, you must use substitutions:
    \s for spaces, \. for period, @ : ! are permitted
    For this User-Agent: Bot mailto:craftbot@yahoo.com use this in your .htaccess: Bot\smailto:craftbot@yahoo\.com

    Then I send bad user agent requests to a page this way:

    RewriteCond %{REQUEST_URI} !/shared/bad-webbot.php$ [NC]
    RewriteCond %{REQUEST_URI} !/shared/403.php$ [NC]
    RewriteRule (.*) /shared/bad-webbot\.php [E=badUserAgent:%0,L]

    First I check that the file being requested isn’t one ofย  my “error” pages. The user agent doesn’t change when I redirect to an error page, so if I don’t make an exception for my error page, the server has a security conflict (you told me to display this page with that security rule, but the page violates the security rule) and gives up by showing a bare “500: Server Error”.ย  Then I redirect the requested file to my “you’re a nuisance” page.

    The E=badUserAgent:%0 sets an environment variable that my bad-webbot.php page can read.

    The ,L says this is the Last thing to check in .htaccess, go right to the page.

    My bad-webbot.php just displays minimal HTML, with no style sheet. But it also logs the IP address and what makes me think they’re a nuisance, in this case which phrase in their user agent triggered the security script. If something is being blocked incorrectly, I can see it in the log.

    One exception I found for user agents was for LinkedIn. “Jakarta” is one of the agents suggested for blocking, but LinkedIn uses this user agent. Another I made an exception for is Alexa.

    LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com)

    Here’s how I made the exceptions:

    SetEnvIfNoCase User-Agent ia_archiver\ \(+http://www\.alexa\.com\/site\/help\/webmasters;\ crawler@alexa\.com) !badUserAgent
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http://www\.linkedin\.com) !badUserAgent

    Notice how I put a backslash before all spaces, periods and slashes inside the user agent string.

    The ! before the variable (badUserAgent) un-sets the environment variable.

  • What Does “Unlimited” Hosting Mean?

    When you are searching for hosting accounts, you will often see “unlimited disk space” and “unlimited bandwidth” as top features. A few years ago, hosting providers would give you a clear limit on how much space and bandwidth they would give you; if you exceeded either one, your hosting provider would either a) charge a lot for more space or bandwidth, usually without even having sent you a message you were approaching your limit, or b) shut down your hosting account, again usually without warning. So “unlimited” was a really good thing.

    What Does “Unlimited” Mean?

    It means if you are using your hosting account for hosting a normal personal or small-business site, they don’t monitor your disk space or traffic. It doesn’t mean you can host a file sharing service for thousands of customers, or host thousands of hours of video for a movie rental business or porn site, or have millions of site visitors like a large business would.

    If you show up on their list of accounts using the most server resources, you may get instructed to reduce your usage. These resources include disk space, bandwidth (how many bytes are transferred and/or transferred at once), memory or CPU usage (a program running out of control), number of files stored (huge number of files slows down the server since the file index gets enormous, and operating systems limit how many files can be on a single hard drive).

    Host Gator says it this way:

    There are no set limits on the disk space or data transfer (bandwidth) that we provide in our shared and reseller hosting plans. We want you to have the resources you need to build a great online presence.

    That being said, we do require all customers to be fully compliant with our Terms of Service and utilize disk space and bandwidth in the normal operation of a personal or small business website. While it is rare, we may need to put constraints on accounts that are using resources that impact other customers on the same server.

    Typically, customers only run into issues if they use their accounts for storage or file sharing, which is not what our services are intended to support. In accordance with our Terms of Services the disk space and bandwidth you use must be integrated into the normal operation of your website.

    For Example, customers who are affecting other clients or are using 25% or more of system resources for longer then 90 seconds would be in violation. Please see our TOS or contact us for complete details and restrictions.

    If you need more bandwidth or disk space, pay your hosting provider for the extra amount you need. Don’t flame your hosting provider about “they said unlimited” when you’re using more resources than 99.9% of their customers. (more…)

  • Security for Hosting Accounts, for WordPress Sites

    There are many things you can do to make WordPress itself more secure, and I’ll cover those in another post.

    The first level of security for WordPress should be your hosting account, done at the server. But with almost all hosting providers, you have to install security; good security almost never comes with the hosting account — most hosting providers don’t know security, they know how to provide an account that matches everyone’s basic needs.

    There are major hosting companies that literally think they have good security because they have an armed guard outside their server room. Companies like these tend to have outdated server software; haven’t installed dedicated security software and dedicated someone to monitoring international security discussion groups for issues, haven’t done anything to counter these new issues.

    A few companies, such as Sucuri can help you identify if your site is compromised, and clean up the malware. You still should have good security in place, to prevent as many attacks as possible.

    You will likely have to make some exceptions to any security system, to allow requests for some of your pages. For example, ‘administrator’ is a common word targeted by hackers (for example, trying to get into database administrator tools), but also is legitimate for several non-computer web site topics.

    You can block bad people from accessing your site through bad characters or phrases in several places in the URL, (including some you might not expect); or through bad cookies, that you might not even see.

    You could detect them by the User Agent they use (though the smarter ones pretend they use a normal browser, many use the User Agent to brag about who they are).

    You could try to block them by their IP address, but hackers know how to constantly change their IP address, so this is a wasteful approach. You would have to constantly be updating your ‘banned IP’ list, and having your server check through the huge list for every request, just slows down your entire web site.

    Security experts have identified some very common methods of attacks, and nuisances that waste your server resources — and come up with very effective ways to block them.

    I added having my server keep a log of what pages where blocked And Why (what phrase or trick was thwarted by my security systems, and what part of the security script caught their foul deed) — so if the security is blocking requests for a real page on your site, you can easily make an exception to the rule, leaving the protection in place for all other pages on your sites.

    This is a big deal. When an important part of your site is blocked, you might not even know about it. Then you want to fix it quickly, not having to somehow guess right (literally, in the past I had to try removing large pieces of a security system, to hope one of the pieces was to blame, not a combination of security rules). Trying to fix a problem ‘blind’, in a very detailed technical part of your web site, under pressure, is No Fun.

    I’ll be writing how to stop each type of bad trick hackers play, so you understand how it works; and if you know .htaccess fairly well you can implement the security and reporting yourself.

    If you don’t know .htaccess well, or just want me to take care of it for you, contact me and I can probably set it up for you.

    You don’t have to leave security for your WordPress sites up to luck. Stop those bad people before they damage your site.

  • Configuring XAMPP for Multiple Web Sites

    To use XAMPP for developing multiple web sites, specify a ‘host name’ for each web site to use. Each web site will have its own folder on your computer. Link a host name, to a folder with your web site files. Edit the web site files, view them on your web browser (skipping the normal FTP step for each change); when the page is working, publish it to the Internet.

    You can define your own host names. Some people use .local for their naming convention (http://www.yourdomain.com on the Internet, http://www.yourdomain.local on your development computer). Or use local.yourdomain.com, which should be looked for on your computer before on the Internet. I like a simpler one, since I’m doing it only for me: yd.c (Yes, you can name it anything you want, on your own computer only). Two or three letter abbreviation, and .c, you’d be amazed how typing 4 characters instead of a long domain name, again and again, matters in developing and testing a web site.

    You define “your own host name” in two places, one for XAMPP, one for Windows. (more…)

  • IIS Servers Do Not Always Set Document Root

    IIS servers doesn’t always set the PHP standard variable, $_SERVER[‘DOCUMENT_ROOT’]

    How do you set that in one place, your configuration file that you include in all your php programs, so the rest of your code has the document root set like on Apache servers?

    Output $_SERVER to see what IS given that you might be able to use:

    echo "
    _SERVER:
    "; print_r($_SERVER); echo "

    _ENV:
    "; print_r($_ENV); echo "

    ";

    In this example, the SCRIPT_FILENAME and SCRIPT_NAME are set.

    Modify the code below to use what is given to get DOCUMENT_ROOT:

    if (!isset($_SERVER['DOCUMENT_ROOT']) || $_SERVER['DOCUMENT_ROOT'] === '') {
      $_SERVER['DOCUMENT_ROOT'] = substr($_SERVER['SCRIPT_FILENAME'], 0, -strlen($_SERVER['SCRIPT_NAME']));
      putenv('DOCUMENT_ROOT='.$_SERVER['DOCUMENT_ROOT']);
    }
    

    Now you can use $_SERVER[‘DOCUMENT_ROOT’] normally:

    $docroot = getenv("DOCUMENT_ROOT"); 
    include_once "$docroot/folder/yourfile.php"; 
    
  • Example of Error Reporting from Error 403:Permission Denied

    Here are some actual error messages I received, triggered by hackers or spammers. I’ve only edited them to not disclose my server secrets.

    Definitely read the main post Error Reporting from .htaccess.

    Here’s the error log entry:

    htaccess Errors = badRequestString:.asp--asp | 220.161.96.101 Accessing: lcblog.lernerconsult.com, /bokeindex.asp Tue Sep 3 2013 10:44:23 am MST 

    Here is the email subject:

    403 lcblog.lernerconsult.com /bokeindex.asp

    Right away, I know a hacker got blocked, I don’t need to read the email. Delete.

    Here’s what the email contains: What triggered the 403:Permission Denied error (the use of .asp), who tried to load what, info about them including what cookies they have and browser type. Then I can see the system PHP error log, so I know the status of my site; yeah I know I’m sending that via an insecure email. (The 403 Errors are logged in a different file, not cluttering my system error log.) Then the PHP system variables, $__SERVER and $_ENV (these I usually keep commented out of the emails, now that I’ve made sure I have the info I need, and if I’m tracking a big problem, it’s really nice to have).
    (more…)

  • Web Site Development Tools (Windows and OS/X)

    Web Site Development Tools (Windows and OS/X)

    You really should use an FTP program. (No, don’t use your web hosting company’s HTML file browser. Not as fast, easy, reliable. Also, don’t edit plugin or theme files using WordPress built-in editor, you need a programmers editor, and then FTP.) Windows FileZilla or FileZilla Portable; OS/X FileZilla Client or just search for FileZilla on download.cnet.com, it’s completely free and well done. Find out from your hosting provider if you can connect securely (SFTP is most common).

    If you don’t already have a good programmers editor, get Notepad++, Notepad++ Portable, or for OS/X TextWrangler or BBEdit look like good choices (but I haven’t used either). TextWrangler vs BBEdit Comparison. Both are from the same company, so get TextWrangler (free) until you know you Need a feature in BBEdit.

    I have clients who use CoffeeCup Free HTML editor, or who have purchased the full version. Very nice. I haven’t used their other tools, I either already had free tools that work great, or wasn’t interested, but those tools all look well done. http://coffeecup.com/

    Having a development server lets you put only working pages on your public web site. I use XAMPP, a full free Apache server, with PHP, Perl, MySQL, and more, to run on your Windows computer. Even a portable version (install on a USB drive, have a web site development server on any Windows computer). Changes the development flow; instead of making updates with edit-upload-refresh browser-repeat, updates become edit-refresh browser. Small change, but it really adds up. Plus of course, it enforces developing and testing on one server, putting the working product on the production server. Develop WordPress plugins on your notebook, without crashing your production WordPress multi-site setup with 30 client blogs.

    If you want a full professional HTML/PHP/Javascript development environment with debugger, I’ve used NetBeans IDE and like it. Versions for Windows, OS/X and others. Get the “PHP Bundle” unless you know you are going to use other languages; you can always “add or remove packs later using the IDE’s Plugin Manager (Tools | Plugins)”. But unless I am working on something where stepping through the code to find bugs is what I need to do, I find I use NotePad++ most, perhaps just because I learned it first.

    For website development you have to have Firefox, with the Firebug addon. And it’s really good to have Google Chrome too, there are occasional CSS slight differences; mostly I’ve found I was sloppy with CSS sometimes, Chrome would show my sloppiness where Firefox would interpret my CSS to do what I meant. Chrome has the developer tools built in (the Inspector), that look a lot like Firebug; both let you see all the CSS statements are loaded for the element, which are over-ridden vs active, and adjust the CSS until you see the results you want. Both have a lot more, and that’s the feature you’ll use every time something on any page doesn’t look right.

    (I don’t use Internet Explorer except occasionally I quickly check my site displays in an older version; IE9 came on my new computer. Any version of IE older than that gets the same standards compliant, responsive, minimal HTML, formatted by CSS web site that I give to any smart phone, plus a very small IE-specific CSS file that makes it display simply; anyone using old IE today is used to web pages not looking great.)

    I use the Fireshot plugin for screen captures, Firefox/Chrome/IE. Excellent for communicating technical visual things with other people.

    Check out Xplorer2 for file browsing, much easier to have two panes in a single window, than using Windows Explorer. Use bookmarks for your favorite folders, instead of endlessly navigating up and down the tree of folders. (on download.cnet.com)

    For images, I use IrfanView for viewing and minor edits such as cropping and color balance. GIMP is the best free image editor; I barely know how to use it for simple things; graphic artists compare its features to PhotoShop.

    For keeping all my passwords for all those sites and banks and stores, settings for FTP sites, settings for databases, etc, I use KeePass Portable (on download.cnet.com)

    GMail and Google Hangouts have custom email accounts for free, view email from any web browser, forward GMail messages to any POP or IMAP account (e.g. on Thunderbird). Google Hangouts is connected to a GMail account, chat audio or webcam audio/video. Screen sharing, if you do any technical support you can guide the other person as you watch their screen. Completely free calls to any USA phone number.

    VLC Media Player: http://videolan.org/vlc excellent media player capable of reading most audio and video formats.

    7 Zip: http://7-zip.org An open source, free alternative to WinZip, has higher compression, great integration with Windows Explorer or xplorer2.

    Adobe Reader: http://get.adobe.com/reader the standard free PDF viewer.

    Audacity: http://audacity.sourceforge.net for recording & editing audio files, a lot of professional-level multi-track editing capabilities. Easy for trimming audio (e.g. the long pause from starting recording to start of talking), and making people who talked at different volumes sound the same. Open source.

    Evernote: http://evernote.com Scan your notes, receipts, etc, will OCR the content, save it, and make it searchable. Free.

    GIMP: http://gimp.org (free download)
    An open source program used to create & edit – free alternative to Photoshop.

    Open Office: http://openoffice.org (free download)
    Open source office suite software – word processing, spreadsheets, databases, presentations. Reads .csv files better than Microsoft Office (if a text field has multiple lines, MSOffice can’t read it).

    Panda Cloud Antivirus (download.cnet.com) or AVG: http://free.avg.com (free download)
    Anti-virus and anti-spyware protection.

    BrowserShots: http://browsershots.org (free online tool)
    Use this to see how your website look in various browsers, browser versions, operating systems.


    Other Software, Others Recommended

    CamStudio: http://camstudio.org (free download)
    Lets you record all screen & audio activity on your computer and create video files.

    CCleaner: http://ccleaner.com (free download)
    Removes unused files from your pc allowing Windows to run faster and freeing up space.

    Color Cop: http://colorcop.net (free online tool)
    A multi-purpose color picker – great for web designers and programmers.

    Down For Everyone: http://downforeveryoneorjustme.com (free online tool)
    Is your site down? Use this tool to see if your website is down for other people.

    DupeFree: http://dupefreepro.com (free download)
    Quickly check for duplicate content & LSI keywords.

    Give Away Of The Day: http://giveawayoftheday.com (free download)
    Unique site that offers you a free license digital product daily.

    Launchy: http://launchy.net (free download)
    Opens your documents, project files, folders, and bookmarks with just a few keystrokes .

    NicheBot Classic: http://nichebotclassic.com (free online tool)
    Online keyword research tool helps you target the correct keywords.

    OSWD: http://oswd.org/ (free downloads)
    Open Source Web Design offers free web design templates.

    PDF995: http://pdf995.com (free download)
    Use this tool to easily convert files to PSD format.

    PDF to Word Converter: http://pdftoword.com (free online tool)
    Easily create editable Word Doc files from PDF content โ€“ for legit purposes only! ๐Ÿ™‚

    Pixie: http://nattyware.com/pixie.php (free download)
    Great for web designers – just point to a color and it will tell you the code value for that color.

    Private Label Rights Forum: http://resell-rights-weekly.com/forum (free online tool)
    Very helpful forum with lots of good info on internet marketing. Friendly members too.

    Resell Rights Weekly: http://resell-rights-weekly.com/ (free downloads)
    Free membership where you can download over 150 PLR/RR products for free.

    Roboform: http://roboform.com (free download)
    Easily & safely manage your passwords.

    ScreenHunter: http://wisdom-soft.com/sh/sh_free.htm (free download)
    Software that allows you to โ€œcaptureโ€ any part of your desktop, a window or full screen.

    ShortKeys: http://shortkeys.com (free download)
    Allows you to set up replacement text or paragraphs for any user defined keystrokes.

    SpyBot: http://safer-networking.org (free download)
    Effectively detects and removes spyware from your PC.

    Textpad: http://textpad.com (free download)
    A powerful text editor, for editing HTML code.

    TimeLeft: http://nestersoft.com/timeleft (free download)
    A countdown, reminder, clock, alarm clock, stopwatch, timer, & web countdown tool.

    Tweet Deck: http://tweetdeck.com (free download)
    Great for staying in touch with your contacts across Twitter, Facebook, MySpace and more.

    Kompozer: http://kompozer.net (free download)
    An easy to use WYSIWYG HTML editor. Less buggy than NVU (the project was picked up where NVU left off). But doesn’t know anything about PHP, won’t even open a PHP file (copy/paste results into your PHP file, in NotePad++.) As of 9/1/2013: “Latest development version: 0.8b3 (2010-02-28)”, so the project has halted. I recommend get the CoffeeCup Free HTML Editor, which displays the preview in a portion of the screen. Or if you really want to have WYSIWYG web editing, use WordPress!

  • Testing .htaccess Lines Without Crashing Your Site

    On Apache servers, you put many configuration settings in your .htaccess file.

    Syntax Errors in your .htaccess file will crash your entire site. If you have errors in your /public_html folder .htaccess, you will crash all sites set up as sub-domains or parked domains as well.

    This post is not a tutorial on modifying .htaccess files, but on how to test a complex command outside of your main site.

    There are many techniques for identifying which line is the one crashing your site. Your site error log may say a certain command is not allowed in your .htaccess (your hosting provider may have to make the setting change for you). Or you restore a version that you know worked, test it (make sure it still works), and add small chunks of the bad file: works to line 57, crashes by line 100, works to line 70, crashes by line 85, works to 75, crashes by 80, ah it’s line 77. (When narrowing down which chunks work, make sure you keep section tags matched, having unmatched .htaccess section tags will definitely crash your site.)

    Testing Syntax Outside Your Main Site

    Your site is functioning. You want to add something to .htaccess, without crashing the site.

    Before you do anything else, Back Up to a new folder on your computer (very deliberately Not to the folder you use every day for web site work!) your functioning .htaccess file. Then rename it in this special folder, with date and status, and make it a .txt file). Keep calm, keep sane, be clear. Have a working version you can fall back on. Keep your working version safe.

    Test the new command first, before adding it to your main site, someplace with no effect to normal site visitors.

    You could have a .htaccess file in any folder. The .htaccess from the root folder is read first, then any .htaccess files in sub-folders to get to the folder a web page is in. (Don’t replicate all the commands from the root .htaccess, and don’t make a .htaccess in each folder unless you need a change from the folders above, that just slows down your web site.)

    Make a new folder, a sub-folder of your main site. Any made-up valid folder name. Put a minimal HTML file in that folder. Here’s an example:

    
    
        Minimal HTML file
        
    
    
    

    This is a Minimal HTML file for Testing.

    Test that this page displays in your web browser.

    Now put a new, empty .htaccess file in this new folder. (The file name must start with a period, so it may be easiest to use your FTP program to create a new file on the server, and then use your FTP program to open it for editing; most Windows programs don’t understand file names starting with a period…)

    Put a comment (any line that starts with a # is a comment) in this .htaccess file, save it, make sure the test page still displays.

    Now you can begin actual testing of the line that was causing all the trouble.

    In the following example, start with a very simple statement, gradually add a piece at a time and make it work.

    Each line of the example below was how I tested a long User-Agent. Below is the final result, with the bad lines commented out.

    This one works:

    SetEnvIfNoCase User-Agent LinkedInBot itWorked

    This has a slight change, the parenthesis, and fails:

    SetEnvIfNoCase User-Agent LinkedInBot(compatible itFailed

    The failure is a 500 Server Error. (Ignore the itWorked or itFailed environment variables being set, that’s not what the failure is, the failure is an illegal use of a special character in the statement.)
    Change to this and it works again:

    SetEnvIfNoCase User-Agent LinkedInBot\(compatible itWorked

    The backslash converts the meaning of the opening parenthesis from special character to something to display. (Parentheses enclose partial results that can then be referred to, and the missing closing parenthesis makes the syntax invalid, 500 Error.)

    Then add a single line of code and test it (in order to test the bad lines below, you’ll have to remove the leading #… as a comment, of course it’s valid!)

    Notice the difference between each line and the one before it.

    Working Example: Testing for a User Agent

    Ignore the word wrapping of long lines, on this screen and in your text editor. Each command must be on a single line (i.e. the command ends when you press the Enter key). Don’t type line numbers, displayed here only to help you see what is a separate line.

    # actual user agent string:  LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com) 
    
    # .htaccess lines that start with # are comments. Comments can Only start at the beginning of a line.
    
    # If the User-Agent system variable contains the value "LinkedInBot" (not case sensitive), set an environment variable "itWorked":
    SetEnvIfNoCase User-Agent LinkedInBot itWorked
    
    # SetEnvIfNoCase User-Agent LinkedInBot(compatible itFailed
    SetEnvIfNoCase User-Agent LinkedInBot\ \(compatible itWorked
    # must escape an open parenthesis ( by preceding it with a back-slash \
    # must escape a space meant as part of the string (so it isn't separating parameters)
    
    SetEnvIfNoCase User-Agent LinkedInBot/1\ \(compatible itWorked
    # a forward slash / is okay
    
    # SetEnvIfNoCase User-Agent LinkedInBot/1.0\ \(compatible itFailed
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible itWorked
    # must escape a period .
    
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5 itWorked
    # semicolon ; is okay
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0; itWorked
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons itWorked
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons- itWorked
    # hyphen - is okay (test if it works when could be part of a character range e.g. a-f)
    
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1  itWorked
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http  itWorked
    # plus + is okay
    
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http://www  itWorked
    # colon slashes :// are okay
    
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http://www\.linkedin\.com  itWorked
    SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http://www\.linkedin\.com)  itWorked
    # closing parenthesis (at least when isn't an open parenthesis it could match) is okay
    
  • Server alert you of File Not Found and other Errors

    I want to know when there are errors on my site.

    “404: File Not Found” errors can be from forgetting to upload an image, or from typing a URL wrong for a link to another page on my site. They can also be from people typing a file name wrong (some words are commonly mis-spelled). I can correct all of these, if I know about them.

    Most people have to remember to check their site logs. (But they don’t.) I want the option of having the server send me an email.

    Yes, I get emails about made-up names search engines look for, and made-up names spammers search for. I just delete these emails, part of web site maintenance (or I turn off emails about errors that didn’t start from my site, e.g. hackers searching). A few search bots are so bad, I have my site not send me emails about their “missing files”; the Bing-bot is drunk.

    I also want to know about some categories of 403: Access Denied requests, to make sure that none are for files that should be permitted. I’ve had some WordPress plugins, for example, that produced file names with double slashes in them, which my security system was blocking; I needed to know that was going on, and what exactly was making those legitimate file requests get blocked. I needed full disclosure from my server.

    Here is how I have the server give me the reports I need. (Another post will cover the security system I use, and the modifications to get the full disclosure from it.)

    What you Need to Use This

    I’m writing to experienced PHP programmers. You have to be able to understand, install, test PHP programs. This works on my server, LunarPages hosting and an IIS server, but accesses server variables that might be different on your server; there is no way I can know the details of your server (unless you hire me to install this for you). This might not fully work on your server, or might need modification! If you can’t debug PHP, for server-level functions, don’t try this; have me or another programmer do this for you.

    This works best on Apache web servers. This also works on IIS servers, though they will probably give less detailed reporting, and may block writing the error log entries. (I’m not going to give IIS instructions here, if you have an IIS server you probably already know how to adapt these instructions. In another post I’ll show my web.config file changes for IIS.)

    How to Call This

    I have my server error pages, 403.php 404.php 500.php (specified in .htaccess) include errortowebmaster.php. I have all these files in /public_html/shared (and have symbolic links defined so the shared folder literally does get shared by all my web sites).

    Initializing errortowebmaster.php

    
    

    So far, I am doing some standard initializing variables.

    LinkChecker is a good free program to check for broken links on your site; I want to not get an email for each link it finds, since it produces good reports itself. I simplify the http agent field (and have these defined in one place should the agent ever change).

    What Caused 403:Access Denied Errors?

    I am using the 5G Blacklist/Firewall from http://perishablepress.com/5g-blacklist-2013/ to block access by hackers and spammers. It works on commonly used patterns in several server fields, not on constantly-updated IP addresses or constantly-spoofed User Agent fields. I highly recommend reading their pages, so you understand how it works.

    However, the 5G Blacklist needs testing, to make sure nothing on your server gets blocked inadvertently. Another post will show how I customized the 5G Blacklist script; this post shows how I use server variables I set, to give me reports — what phrase triggered what section of the Blacklist.

    if ( (getenv("REDIRECT_noRewrite") !== FALSE) || (getenv("noRewrite") !== FALSE) ){
    	$htaccessErrors[] = 'Module mod_rewrite.c not installed or not enabled';
    }
    if (getenv("REDIRECT_dotHTLocation") !== FALSE) {
    	/* for testing only, which .htaccess file is being triggered? The root or a subdomain? Testing showed that on LunarPages hosting, only the QueryString section of 5G Blacklist needs to be in a subdomain's .htaccess file -- easier to maintain updates with most of the 5G Blacklist in only one place */
    	$htaccessErrors[] = '.htaccess location:' . getenv("REDIRECT_dotHTLocation");
    } elseif (getenv("dotHTLocation") !== FALSE) {
    	$htaccessErrors[] = '.htaccess location:' . getenv("dotHTLocation");
    }
    
    if (isset($_SERVER['REDIRECT_noUserAgent']) || isset($_SERVER['noUserAgent']) ) {
    	$htaccessErrors[] = 'NoUserAgent';
    }
    
    /* root .htacess sets variable, subdomain .htaccess sets REDIRECT_variable, since the root checks first then redirects to the subdomain */
    
    /* variable names must exactly match what shows up in $_SERVER, is case sensitive (e.g. badQueryString not BadQueryString) */
    if (getenv("REDIRECT_badQueryString") !== FALSE) {
    	$htaccessErrors[] = 'badQueryString:'.getenv("REDIRECT_badQueryString");
    	$sendMail = $sendMail ? $emailQueryString : false;
    } elseif (getenv("REDIRECT_REDIRECT_badQueryString") !== FALSE) {
    	$htaccessErrors[] = 'badQueryString:'.getenv("REDIRECT_REDIRECT_badQueryString");
    	$sendMail = $sendMail ? $emailQueryString : false;
    } elseif ($querystring=='QUERY_STRING') {	/* from IIS web.config */
    	$htaccessErrors[] = 'badQueryString';
    	$sendMail = $sendMail ? $emailQueryString : false;
    }
    
    if (getenv("REDIRECT_badRequestString") !== FALSE) {
    	$htaccessErrors[] = 'badRequestString:' . getenv("REDIRECT_badRequestString");
    	$sendMail = $sendMail ? $emailRequestString : false;
    } elseif (getenv("REDIRECT_REDIRECT_badRequestString") !== FALSE) {
    	$htaccessErrors[] = 'badRequestString:' . getenv("REDIRECT_REDIRECT_badRequestString");
    	$sendMail = $sendMail ? $emailRequestString : false;
    } elseif ($querystring=='URL_REQUEST_STRING') {	/* from IIS web.config */
    	$htaccessErrors[] = 'badRequestString';
    	$sendMail = $sendMail ? $emailRequestString : false;
    }
    
    if (getenv("REDIRECT_badUserAgent") !== FALSE) {
    	$htaccessErrors[] = 'badUserAgent:' . getenv("REDIRECT_badUserAgent");
    	$sendMail = $sendMail ? $emailUserAgent : false;
    } elseif (getenv("REDIRECT_REDIRECT_badUserAgent") !== FALSE) {
    	$htaccessErrors[] = 'badUserAgent:' . getenv("REDIRECT_REDIRECT_badUserAgent");
    	$sendMail = $sendMail ? $emailUserAgent : false;
    } elseif ($querystring=='USER_AGENT') {	/* from IIS web.config */
    	$htaccessErrors[] = 'badUserAgent';
    	$sendMail = $sendMail ? $emailUserAgent : false;
    }
    
    if ( getenv("REDIRECT_badRequestMethod") !== FALSE ) {
    	$htaccessErrors[] = 'badRequestMethod:' . getenv("REDIRECT_badRequestMethod");
    	$sendMail = $sendMail ? $emailRequestMethod : false;
    } elseif ( getenv("REDIRECT_REDIRECT_badRequestMethod") !== FALSE ) {
    	$htaccessErrors[] = 'badRequestMethod:' . getenv("REDIRECT_REDIRECT_badRequestMethod");
    	$sendMail = $sendMail ? $emailRequestMethod : false;
    }
    
    if ( (getenv("REDIRECT_badCharsInRequest") !== FALSE) || (getenv("REDIRECT_REDIRECT_badCharsInRequest") !== FALSE) ) {
    	$htaccessErrors[] = 'badCharsInRequest (e.g. CRLF)';
    	$sendMail = $sendMail ? $emailBadChars : false;
    }
    /* testing, don't know yet which .htaccess catches badCharsInRequest problems */
    if ( (getenv("REDIRECT_badCharsInRequestLC") !== FALSE) || (getenv("REDIRECT_REDIRECT_badCharsInRequestLC") !== FALSE) ) {
    	$htaccessErrors[] = 'badCharsInRequestLC (e.g. CRLF)';
    	$sendMail = $sendMail ? $emailBadChars : false;
    }
    
    if ( (getenv("REDIRECT_badCookie") !== FALSE) || (getenv("REDIRECT_REDIRECT_badCookie") !== FALSE) ) {
    	$htaccessErrors[] = 'badCookie';
    	$sendMail = $sendMail ? $emailCookie : false;
    }
    /* testing, don't know yet which .htaccess catches cookie problems */
    if ( (getenv("REDIRECT_badCookieLC") !== FALSE) || (getenv("REDIRECT_REDIRECT_badCookieLC") !== FALSE) ) {
    	$htaccessErrors[] = 'badCookieLC';
    	$sendMail = $sendMail ? $emailCookie : false;
    }
    
    if (isset($_SERVER['REDIRECT_ERROR_NOTES'])) {
    	$htaccessErrors[] = 'Error Notes:'.$_SERVER['REDIRECT_ERROR_NOTES'];
    } elseif (isset($_SERVER['REDIRECT_REDIRECT_ERROR_NOTES'])) {
    	$htaccessErrors[] = 'Error Notes:'.$_SERVER['REDIRECT_REDIRECT_ERROR_NOTES'];
    }
    
    /* badNuisance should be sent directly to bad-webbot.php, display minimal page. Nuisance in QUERY_STRING would arrive here */
    if (isset($_SERVER['REDIRECT_badNuisance'])) {
    	$htaccessErrors[] = 'Nuisance:'.$_SERVER['REDIRECT_badNuisance'];
    	$sendMail = false;
    } elseif ($querystring=='NUISANCE') {
    	/* from IIS web.config */
    	$htaccessErrors[] = 'Nuisance';
    	$sendMail = false;
    } 
    
    if (isset($_SERVER['REDIRECT_badBot']) || isset($_SERVER['REDIRECT_badBadHacker']) ) {
    	/* badBot set in /shared/blackhole/.htaccess, for the George Lerner modified version of http://perishablepress.com/blackhole-bad-bots/ which makes lines to cut/paste into .htaccess */
    	if (isset($_SERVER['REDIRECT_badBot']) ) {
    		$htaccessErrors[] = 'badBot '. $_SERVER['REDIRECT_badBot'];
    		$sendMail = $sendMail ? $emailBot : false;
    	}
    	/* If an IP address gives too many 403 errors, add them to the badBadHacker list in .htaccess. Future enhancement, have this file keep count, make a log file with lines to cut/paste into .htaccess */
    	if (isset($_SERVER['REDIRECT_badBadHacker']) ) {
    		$htaccessErrors[] = 'blacklisted by IP';
    		$sendMail = $sendMail ? $emailHacker : false;
    	}
    } elseif ($querystring=='IP_ADDRESS') {
    	/* from IIS web.config */
    	$htaccessErrors[] = 'blacklisted by IP';
    	$sendMail = $sendMail ? $emailHacker : false;
    }
    
    

    On my server, custom server variables get prefixed with 'REDIRECT_' and I tested both with and without the prefix; this is definitely something that your server could do differently. Check the $_SERVER and $_ENV variables for the actual variable names on your server.

    Very Detailed Error Display for My Computer

    Put your IP addresses (e.g. home computer, work computer, and smart phone) in $myipaddress, set in your secret configuration file (secret because it contains your IP address, which will let baddies see your server configuration). Not "secure" but probably "secure enough"; someone who sees your screen can get anything they want from you; someone who has access to your configuration file has full access to your site. Sometimes is Very useful for debugging to see the server variables, especially when I am configuring a new client's account. Just browse to any non-existent file name on their web site from my computer, and my 404.php shows me (and only me) $_SERVER and $_ENV.

    For any IP address I know, I also display my name for it. For example, don't put the local coffee shop in the "My IP" list, but it makes sense to identify the coffee shop so you know "that was me testing things" or "hmm, I was at the coffee shop, but didn't access That file..." (Pay attention to who can see your screen, even from a distance!) I also put names to the IP address of web site clients, since they will have a lot more errors as they develop new pages on their site, (those few times I notice an ongoing problem and give them the solution, they love it).

    Displaying the Detailed Troubleshooting & Error Information

    Note: For getting this to display well in WordPress, I changed <pre> to <code> (open and close tags) in the next section. You'll probably like the display better if you use pre in your code.

    if (in_array($ip, $myipaddress)) {
    	echo "
    .htaccess Errors:
    "; print_r($htaccessErrors); echo "
    "; echo "
    _SERVER:
    "; print_r($_SERVER); echo "

    _ENV:
    "; print_r($_ENV); echo "

    "; if (isset($_GET)) { foreach ($_GET as $arg) { $clean = filter_input(INPUT_GET, $arg, FILTER_SANITIZE_STRING); // new PHP function print "Get Parameter: $clean
    "; } } if (isset($argv)) { // IIS (Cart32) leaves in $_SERVER['QUERY_STRING'], or $_SERVER['argv'], both unparsed, on error pages. foreach ($argv as $arg) { $clean = filter_input(INPUT_GET, $arg, FILTER_SANITIZE_STRING); print "Argv Parameter: $clean
    "; } } else if (isset($_SERVER['argv'])) { foreach ($_SERVER['argv'] as $arg) { $clean = filter_input(INPUT_GET, $arg, FILTER_SANITIZE_STRING); print "_SERVER argv Parameter: $clean
    "; } } } $ipText = $ip; switch ($ip) { case "12.345.67.89" : case "123.45.678.90" : $ipText .= " (My Home)"; break; case "98.76.54.32" : $ipText .= " (My Work)"; break; default: // $ipText .= " (unknown)"; } $combine = $ipText . " tried to load \n";

    Writing an Error Log

    After some checking for uninitialized variables, write a brief error result to log files. I deliberately keep 403 errors out of the system PHP error log, as they require different attention. (Tempting to move 404 errors to their own file, so many idiot search engines/bots, but then I wouldn't see when I forgot to upload an image... I do, however, note when a request originated from a file on my server, since this is much more likely something I need to fix.)

    if (strpos($requri, $servname) !== false) {
    	/* MVC's IIS server gives full URL and status in requri */
    	if ($status !== '') {
    		$subject = $status.' '.$requri; 
    	} else {
    		$subject = $requri;
    	}
    	$combine .= " $requri";
    } else {
    	$subject = "$status $servname $requri";
    	$combine .= " $servname$requri"; 
    }
    
    $mycookie = "";
    foreach ($_COOKIE as $cookie_name => $cookie_text)
    {
    	$mycookie .= "\t" . $cookie_name . ": " . $cookie_text . " \n";
    }
    
    if (!isset($browser_name)) { $browser_name = "(unknown) "; }	
    // set by script from http://techpatterns.com/downloads/php_browser_detection.php
    if (!isset($browser_ver)) { $browser_ver = "(unknown) "; }
    

    Display Info On Web Browser

    $message = "

    $note

    \n

    $combine

    \n

    Remote Host = $remoteHost

    \n

    Query string = $querystring

    \n

    HTTP Referer = $httpref

    User Agent = $httpagent

    \n

    $today

    \n

    Cookies =

    $mycookie
    \n
    "; $message .= "\nBrowser detected as: " . $browser_name . "version " . $browser_ver; $message .= "\nIP Address: " . $ip; echo $message;

    Sending an Email to Site Administrator

    The email will be sent to the address in $adminemail, defined in your secret configuration file.

    function implode_r($glue,$arr){
            $ret_str = "";
            foreach($arr as $a){
                if ($ret_str === "") {
    				$ret_str .= (is_array($a)) ? implode_r($glue,$a) : $a;
    			} else {
    				$ret_str .= (is_array($a)) ? implode_r($glue,$a) : $glue . $a;
    			}
            }
            return $ret_str;
    }
    if (!isset($logfile)) { 
    	$logfile = getenv("DOCUMENT_ROOT") . "/error_log";
    }	
    if (!isset($deniedLogfile)) { 
    	$deniedLogfile = $logfile.'403';
    }
    if (!file_exists($logfile)) {
    	$fh = @fopen($logfile, 'w'); 
    	if ($fh !== FALSE) { fwrite($fh, "ErrorToWebMaster New Error File\n"); fclose($fh); }
    }
    if (!file_exists($deniedLogfile)) {
    	/* some servers prohibit fopen, so @ before it to prevent error messages */
    	$fh = @fopen($deniedLogfile, 'w'); 
    	if ($fh !== FALSE) { fwrite($fh, "ErrorToWebMaster New 403 Error File\n"); fclose($fh); }
    }
    if (isset($htaccessErrors)) {
    	$htaccessErrorsStr = implode_r(" | ",$htaccessErrors);
    	/* Cart32 wimpy IIS hosting doesn't allow error_log ("permission denied") so @ before it */
    	@error_log("htaccess Errors = $htaccessErrorsStr | $ipText Accessing: $servname, $requri $now \n",3,$deniedLogfile);
    } else {
    	@error_log("$ipText Accessing: $servname, $requri $now \n",3,$logfile);
    	$htaccessErrorsStr = '';
    }
    
    /* $message was for on screen, $message2 is for emailing */
    $message2 = "htaccess Errors = $htaccessErrorsStr\n
    $combine \n
    Remote Host = $remoteHost\n
    Query string = $querystring \n
    HTTP Referer = $httpref\n
    User Agent = $httpagent \n
    $today \n
    Cookies = \n$mycookie \n";
    
    $message2 .= "\nBrowser detected as: " . $browser_name . "version " . $browser_ver;
    
    $fh = @fopen($logfile, 'r');
    if (filesize($logfile) == 0) {
    	$theData = "";
    } else {
    	$theData = fread($fh, filesize($logfile));
    }
    fclose($fh);
    $message2 .= "\n\n[Error Log]: $logfile\n" . $theData;
    $message2 .= "\n[End of Error Log]\n";
    $message2 .= print_r($_SERVER,true);
    $message2 .= print_r($_ENV,true);
    
    $to = $adminemail;
    $from = "From: " . $adminemail . "\r\n";
    
    if (isset($_SERVER['REDIRECT_ERROR_NOTES']) ) {
    	$sendMail = false;
    } else $sendMail = true;
    
    if ( (stristr($docroot,"xampp") == FALSE) && ($requri != "/wp-login.php") && ($httpagent != 'LinkChecker/') && ($httpagent != 'LinksManager.com_bot') ) {
    	if ($sendMail !== false) {
    		mail($to, $subject, $message2, $from);
    	}
    }
    ?>
    

    Questions?

    Post your comments or questions here, and of course if you would rather I set this up for you and get it working on your web site, let me know. Contact Me.

  • Robots.txt Tips

    Each web site you write should have a robots.txt file in the main folder, to suggest to search engines which folders you want them to not scan or index.

    You can make this file in any text editor (but not a word processor, must be plain text).

    Comments start with #, so the first line is for your information, specifying which web site this is for. Comments can be after any directive.

    The Sitemap line (can be anywhere in the file, but I put it at top) is a way to tell search engines the full URL where your site map is.

    The “User-agent: *” line says “for all User Agents, this is for you” (The User-agent normally would be browser type, e.g. Firefox or Chrome or IE, but search engines also tell web servers some User Agent.)

    # robots.txt for yoursite.com
    Sitemap: http://www.yoursite.com/sitemap.xml
    
    User-agent: *    # all search engines should ignore the folders Disallowed below
    
    # Maybe have one folder for site images that shouldn't be indexed
    # another for photographs you want indexed by search engines
    Disallow: /images/
    Allow: /photos/
    
    # Here are more examples, use the folders that apply to your site:
    Disallow: /cgi-bin/
    Disallow: /freecontactform/
    Disallow: /junk/
    Disallow: /newsfeeds/
    Disallow: /oldboring/

    You can exclude individual files this way (but probably simpler for you to put files into a separate directory):

    Disallow: /test/junk.html

    If you have WordPress on your site, include these lines:

    # WordPress
    Disallow: /wp-admin
    Disallow: /wp-includes
    Disallow: /wp-content/plugins
    Disallow: /wp-content/cache
    Disallow: /wp-content/themes
    Disallow: /category/*/*
    Disallow: /comments
    Disallow: */comments
    Disallow: /feed
    Disallow: */feed
    Disallow: /manager
    Disallow: /trackback
    Disallow: */trackback
    Allow: /wp-content/uploads

    You can say a specific search engine has different permissions, if you want. (I don’t, all are commented out in the example below)
    Don’t use Allow: /*
    (I actually saw this on some dumb robots.txt teaching site!) Google correctly reads the Allow: /* as overriding the folders for ‘any search’ (see that line above, User-Agent: *), “Ah, everybody but Me shouldn’t read /youtubevideosite/ etc.” and then reports hundreds of errors from your YouTube, Amazon etc. site widgets having bad links that it can’t find on your site. (Of course not, those links are on YouTube or Amazon or the comment writer’s own site.)

    User-agent: Googlebot
    # Disallow:
    # Allow: /images/
    
    # Google Images
    User-agent: Googlebot-Image
    # Disallow:
    # Allow: /images/
    
    # Google AdSense
    User-agent: Mediapartners-Google*
    # Disallow:
    # Allow: /ads/
    
    # digg mirror
    User-agent: duggmirror
    Disallow: /

    See Google’s test page, to make sure Google is reading your robots.txt the way you expect: https://www.google.com/webmasters/tools/ and under Crawl click on Blocked URLs:

    Google webmaster tools

    Robots.txt does not provide Any security. Use .htaccess for that. Robots.txt is a suggestion for good search bots, e.g. Google or Bing, to not bother indexing files. Do NOT mention private areas in robots.txt, you just told bad search bots to go looking there! Don’t bother filling your robots.txt with lines like this, since bad bots don’t even read your robots.txt

    User-agent: Flaming AttackBot   # waste of time, bad bots ignore it
    Disallow: /
    

    There is no way to specify, in robots.txt, to not index “everything except” a single file, there is no use of ‘wild cards’ in file names. Best is put the files you prefer search engines ignore in separate directories.

    There is a way to specify inside an HTML page that search engines shouldn’t bother indexing it. However, this is only seen once the search engine has loaded the page (robots.txt is generally read by search engines before loading any pages in that folder). Simply put a “noindex” meta tag in the <head> section of the page: <meta name="robots" content="NOINDEX, NOFOLLOW, NOARCHIVE" />. I use this on the “thank you” page after a form was submitted, and on my site error pages.

    Also see http://perishablepress.com/robots-notes-plus/.

    Here is my robots.txt in one piece:

    # robots.txt for lernerconsult.com
    Sitemap: http://www.lernerconsult.com/sitemap.xml
    
    User-agent: *
    Disallow: /htm/
    Disallow: /lists/
    Disallow: /sitespecific/
    Disallow: /images/
    Disallow: /cgi-bin/
    Disallow: /cgi-bin/apf4/
    Disallow: /ddtabmenufiles/
    Disallow: /feedforall/
    Disallow: /newsfeeds/
    Disallow: /utils/
    Disallow: /shared/
    Disallow: /shared/youtubevideosite/
    Disallow: /socialbookmarkscript/
    Disallow: /styles/
    Disallow: /youtubevideosite/
    
    # WordPress
    Disallow: /wp-admin
    Disallow: /wp-includes
    Disallow: /wp-content/plugins
    Disallow: /wp-content/cache
    Disallow: /wp-content/themes
    Disallow: /category/*/*
    Disallow: /comments
    Disallow: */comments
    Disallow: /feed
    Disallow: */feed
    Disallow: /manager
    Disallow: /trackback
    Disallow: */trackback
    Allow: /wp-content/uploads
    
    # See test page https://www.google.com/webmasters/tools/ then under Crawl click on Blocked URLs
    
    User-agent: Googlebot
    # Disallow:
    # Allow: /googlefolder/
    
    # Google Image
    User-agent: Googlebot-Image
    # Disallow:
    # Allow: /googlefolder/
    
    # Google AdSense
    User-agent: Mediapartners-Google*
    # Disallow:
    # Allow: /googlefolder/
    
    # digg mirror
    User-agent: duggmirror
    Disallow: /
    
  • Robots.txt Tips

    Each web site you write should have a robots.txt file in the main folder, to suggest to search engines which folders you want them to not scan or index.

    You can make this file in any text editor (but not a word processor, must be plain text).

    Comments start with #, so the first line is for your information, specifying which web site this is for. Comments can be after any directive.

    The Sitemap line (can be anywhere in the file, but I put it at top) is a way to tell search engines the full URL where your site map is.

    The “User-agent: *” line says “for all User Agents, this is for you” (The User-agent normally would be browser type, e.g. Firefox or Chrome or IE, but search engines also tell web servers some User Agent.)

    # robots.txt for yoursite.com
    Sitemap: http://www.yoursite.com/sitemap.xml
    
    User-agent: *    # all search engines should ignore the folders Disallowed below
    
    # Maybe have one folder for site images that shouldn't be indexed
    # another for photographs you want indexed by search engines
    Disallow: /images/
    Allow: /photos/
    
    # Here are more examples, use the folders that apply to your site:
    Disallow: /cgi-bin/
    Disallow: /freecontactform/
    Disallow: /junk/
    Disallow: /newsfeeds/
    Disallow: /oldboring/

    You can exclude individual files this way (but probably simpler for you to put files into a separate directory):

    Disallow: /test/junk.html

    If you have WordPress on your site, include these lines:

    # WordPress
    Disallow: /wp-admin
    Disallow: /wp-includes
    Disallow: /wp-content/plugins
    Disallow: /wp-content/cache
    Disallow: /wp-content/themes
    Disallow: /category/*/*
    Disallow: /comments
    Disallow: */comments
    Disallow: /feed
    Disallow: */feed
    Disallow: /manager
    Disallow: /trackback
    Disallow: */trackback
    Allow: /wp-content/uploads

    (more…)

  • Starting and Stopping Xampp (Apache, MySql) in Windows 7

    There is a lot of confusion on the support boards, people saying they can’t get Xampp to stop, there “must be a bug in Xampp”, or they “had to kill the application with Task Manager”. No, they are trying an incorrect method for closing a Windows Service.

    Some versions of Windows (including Windows 7) prevent applications from starting or stopping services; you should use the Windows Services program to manage services.

    In the “Xampp Control Panel Application”, you specify whether to run Apache and MySql as Windows Services (by checking the “Svc” box).

    If Apache *is not* running as a Windows Service:
    you use the Xampp Control Panel Application to stop and start Apache.

    If Apache *is* running as a Windows Service:
    you use Windows Services to restart Apache. (Start button, search for Services; or Start, Control Panel, Administrative Tools, Services). Click on the Apache service (the version of Apache you are running will be in the service name), then click “Restart the service”.