I had an “interesting” problem on an Exchange server last week… I could access the Exchange Control Panel using https://localhost/ecp but it I tried to use its externally-accessible namespace (which I needed to in order to run the Exchange Hybrid Configuration Wizard), it kept looping on the authentication prompt. The password was correct but it just came straight back to a prompt again…
It turned out to be an issue with HTTP redirection in IIS and, following the MSExchangeGuru post on HTTP redirection issues with the ECP virtual directory I set up HTTP redirection on the Default Website but turned it off for OWA, ECP and the various other virtual directories. I also checked that SSL was not required for the PowerShell virtual directory.
Bipin Giri’s post on configuring URL redirection in Exchange 2013 suggests I need to repeat the same steps for the Exchange Backend Server website too but I didn’t find that necessary (and I’m sure I’ve also read to leave that alone!).
There’s a useful table in the MSExchangeGuru post that summarises the need for an HTTP redirect and whether SSL should be enabled for the website and for each virtual directory but it’s also worth knowing that Morten Nielsen has listed the default virtual directory settings for Exchange 2013 in great detail.
In my recent posts on creating a virtual machine on Windows Azure and connecting to a Windows computer running on Windows Azure, I mentioned endpoints but didn’t explain the process for creating new ones, i.e. opening up new ports for Internet access:
The RemoteDesktop endpoint shown above was created automatically when my virtual machine was provisioned but it may also be necessary to create new endpoints, for example allowing HTTP access over TCP port 80, HTTPS over TCP 443, etc.
To create a new endpoint, open up the virtual machine in the Windows Azure management console, then select Endpoints and click the Add Endpoint button at the bottom of the screen. When creating endpoints, a new endpoint can be established or, if one already exists, this may be selected to load balance between multiple virtual machines. I only have a single virtual machine and so I selected add endpoint:
At this point, specify a name (HTTP would have been a better name than the one I used in the example below), select a protocol, and chose the port numbers:
The endpoint will then be created and the virtual machine will be accessible using the chosen protocol and port numbers:
To test the connection, I connected to my virtual machine over RDP and configured Windows Server roles/features in Server Manager (I installed IIS, just to prove that the machine was Internet-connected – but the server could be running any workload). Then, I connected to my virtual machine’s public DNS using a web browser (I could also have used the public virtual IP address shown in the dashboard for the virtual machine):
I’ve run PHP with Microsoft Internet Information Services (IIS) before (running on a Windows XP laptop) and I seem to remember the installation being quite straightforward. Even so, tonight I was installing PHP 5.2.6 with IIS 6 (on Windows Server 2003 R2 Enterprise x64 Edition) and I ran across a few issues. This post describes what was involved:
- Firstly, PHP can be installed in CGI, FastCGI or ISAPI mode. I used ISAPI.
- Secondly, there is anecdotal evidence that the Windows Installer version is problematic – for that reason you may prefer to use the ZIP file and perform a manual installation (as I did), following the instructions on the IIS Admin blog, which were:
- Extract the files to a location of your choice (I used C:\PHP to keep it simple but C:\Program Files (x86)\PHP would be better).
- Rename php.ini-recommended to php.ini.
- Edit the
extension_dir line in php.ini to read
extension_dir = C:\phpinstallationfolder\ext.
- Add the PHP installation folder to the
%path% system variable (e.g. append
;C:\PHP to the existing path).
- Create a web service extension for PHP using
cscript iisext.vbs /AddFile c:\phpinstallationfolder\php5isapi.dll 1 PHPISAPI 1 â€œPHP ISAPIâ€. The new extension should show in IIS Manager with a status of Allowed.
- Create an application extension mapping for .php files. Following the advice on the IIS Admin blog article that I referenced previously will remove all other mappings so I used the IIS Manager MMC instead (Default Web Site Properties, Home Directory, Configuration to add a mapping to the executable at
c:\phpinstallationfolder\php5isapi.dll using extension
.php for all verbs).
- Create a test file called phpinfo.php containing
<?php phpinfo(); ?>.
- Use a web browser to navigate to http://servername/phpinfo.php and the PHP information page should be displayed.
- If you are running on 64-bit Windows there are some extra steps in order to avoid an HTTP 500 Internal server error or the message %1 is not a valid Win32 application. It seems that this is caused by trying to load a 32-bit application (in this case PHP) inside a 64-bit worker process (as described in Microsoft knowledge base article 895976). To resolve this issue, enter
cscript adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1.
adsutil.vbs is one of the scripts installed into the wwwroot\AdminScripts folder but if you have removed it to secure the server (as I had), then it may be temporarily copied back to the server from another IIS installation.
- To ensure that PHPinfo reflects the correct location of the php.ini file, create an environment variable called PHPRC referring to c:\phpinstallationfolder and restart the server or, alternatively, set the appropriate registry keys (although neither option seemed to have any effect for me).
Readers of this blog may recall that, last year, my open FTP server was hacked. That experience taught me a valuable lesson and earlier today, I needed to establish a secure FTP server installation using Microsoft Internet Information Services (IIS) 5.0 (well, as secure as you can with a protocol that passes authentication details in clear text – of course, there are SSL-secured alternatives available).
The first step was to install only the essential components of IIS, using the unattended IIS installation method that I posted last year.
Once installed, I ensured that the server was fully patched with all relevant security updates before working through the advice from the 10 steps to a secure an FTP server article on windowsecurity.com as well as some more advice which was given to me last year by Craig Schofield, a consultant from Microsoft who was working alongside me at the time:
- Change the default port number for the site from 21 to a non-standard port. This is security through obscurity; however it may not be suitable depending on the clients used to connect to the server.
- Remove all other protocols, using the IIS Lockdown tool to remove sample sites, other protocol mappings (e.g. WebDAV if installed) and to ensure that only the FTP Publishing Service is available (note that there is no point in installing URLScan for FTP servers, as it only applies to HTTP requests).
- Use anonymous access, and only anonymous. This ensures that no security credentials details are passed over the wire (remember, FTP uses clear text for authentication). If user authentication is necessary, use a dedicated account that has no access to any other systems, files or components and the recommendation is to create a local or domain local group, assign this group the required permissions (log on locally, NTFS access), and add users to this group (removing them from the Users group).
- Enable FTP logging, and ideally propagate all logs to a central location. Monitor logs for signâ€™s of attack/penetration.
- Use a virtual private network (VPN) connection between machines, to ensure that all traffic is encrypted. Alternatively, create a secure IP (IPSec) tunnel between server and client.
- Limit the number of FTP site connections to the maximum expected number.
- Assign NTFS security restrictions to the user/group accounts used to access the FTP site.
- Ensure any virtual directories are also protected by NTFS permissions, and are directed at secure locations (not C:\ for example).
- Change the default home folder for the FTP Site from C:\InetPub\ftproot to another folder (preferably not on the C:\ drive so as to avoid a denial of service attack by using all available storage on the system disk)
- Ensure appropriate steps are taken to secure the other accounts on the machine (disable Guest, rename Administrator, assign complex passwords).
Of course, operational requirements will mean that it is not usually possible to implement every one of the above measures, but each one adds to the principle of defence in depth.
Whilst checking my configuration, I came across Microsoft knowledge base article 318380, which lists IIS status codes for HTTP and FTP as well as providing links to the original World Wide Web Consortium (W3C) definitions and some common status codes and their causes.
Last year I blogged about using server side includes in web pages. My SSI code has all been working well on my ISP’s Apache servers, but my development server runs under IIS 5 on Windows 2000. Even with the default document list set to include index.shtml, I was getting HTTP 404 errors for pages that I knew existed. I checked that I had application mappings in place for .shtml files, but what none of the documentation told me was that I needed to change the executable path for .shtml from %systemroot%\System32\inetsrv\404.dll to %systemroot%\System32\inetsrv\ssinc.dll. Once I had made that change, everything jumped into life and my dynamic pages were served as expected.
Whilst looking at the website statistics for my main website, I realised that many users were attempting to access pages that no longer exist on the server. Some may argue that old content should be left in place, but others will disagree and my preferred approach is to redirect requests to the new locations, or at least to provide a polite message that the document has been removed and a link to the home page! Fortunately on an Apache server, this may easily be achieved using an .htaccess directive.
Various types of redirect are available through .htaccess, using the syntax:
Redirect [status] URL-path URL
The status argument can be used to return a number of HTTP status codes:
permanent returns a permanent redirect status (301) indicating that the resource has moved permanently.
temp returns a temporary redirect status (302). This is the default and is assumed if no status argument is given, indicating to the client that the resource has moved temporarily.
seeother returns a “See Other” status (303) indicating that the resource has been replaced.
gone returns a “Gone” status (410) indicating that the resource has been permanently removed. When this status is used the URL argument should be omitted.
Other status codes can be returned by giving the numeric status code as the value of status. If the status is between 300 and 399, the URL argument must be present, otherwise it must be omitted.
For example, a temporary redirection from old file or directory to new:
Redirect /olddirectory/oldfile.html http://yoursite.com/newdirectory/newfile.html
Redirect /olddirectory http://yoursite.com/newdirectory/
or a permanent redirect:
Redirect permanent /olddirectory http://www.yoursite.com/
or redirect with error 410:
Redirect gone /oldfile.html
Full details for Apache users may be found in the Apache HTTP Server documentation.
Microsoft Internet Information Server (IIS) users can find information on redirecting requests to files directories or programs in the IIS 6.0 Operations Guide.
RFC 2616 details all HTTP status (including error) codes.
My ISPs’ Apache servers are configured for index.html and index.htm to be the default documents; however since implementing server side includes in my websites I need index.shtml to be recognised as the default document.
Fortunately, this can be achieved using the following directive in the corresponding .htaccess file:
DirectoryIndex index.shtml index.html index.htm
Microsoft Internet Information Server (IIS) users can find information on setting up default documents in the IIS 6.0 Operations Guide.
One of the features used in my website is custom error pages, which allow errors to be handled using a format that matches other documents on the site.
Apache users can configure custom error messages using .htaccess. Once pages have been created for an error message, include a directive in the .htaccess file as follows:
ErrorDocument error-code document
ErrorDocument 404 /errors/404-notfound.shtml will redirect any page not found (HTTP error 404) errors to display the /errors/404-notfound.shtml document.
Full details for Apache users may be found in the Apache core features documentation.
Microsoft Internet Information Server (IIS) users can find information on configuring custom error messages in the IIS 6.0 Operations Guide.
RFC 2616 details all of all HTTP status (including error) codes.
One of the features used in my website is server side includes (SSI). The SSI code allows my sites to include dynamic information which would otherwise require scripting that may not function correctly with certain browsers.
SSI is pretty simple. Apache users need to edit the .htaccess file in their web root directory to allow SSI, adding the following lines:
AddType text/html .shtml
AddHandler server-parsed .shtml
Some of these may not be necessary if they have been set at a higher level in the Apache configuration by the ISP or server administrator – for full details, see the Apache Tutorial: Introduction to Server Side Includes.
Microsoft Internet Information Server (IIS) users can find information on using server side include directives in the IIS 6.0 Operations Guide.
Once enabled, pages which call the server-based code should be named .shtml (or whatever file extension is defined in the configuration). Because my ISP has configured its servers for the default web page to be called index.htm or index.html, it was also necessary to change the default documents for the website.
One use of SSI to reuse common HTML code (e.g. headers, menus, etc.), but another useful application is to report document information (e.g. date last modified). There are many references on the Internet for SSI options, but one of the most useful is Craig McFetridge’s SSI page on the Carleton University website, with another being the one found on the ThinkQuest Amazing HTML website.
A few weeks back, I updated two websites (which run on my ISPs’ Apache servers) to use various features which improve the experience for users of the site. These features include:
All of these features (and more) may be controlled on an Apache server using a file called .htaccess, which is intended for users who do not have access to the server configuration to make configuration changes on a per-directory basis.
In general, where access to the server configuration is available, then changes should be made at the server level; however in a hosted environment, .htaccess allows content providers to make their own configuration without affecting other users of the server.
Administrators should be made aware that enabling .htaccess on a server does incur a performance hit as Apache will look in every directory on the path for an .htaccess file, and will load the file, whether or not the directives contained within .htaccess are relevant to the HTTP request. For this reason, some ISPs may prohibit the use of .htaccess.
Microsoft Internet Information Server (IIS) does not have an equivalent to .htaccess and all configuration must be carried out using the various IIS administration tools (along with an appropriate organisational security model).
Apache Tutorial: .htaccess files
Comprehensive guide to .htaccess