I'm trying to run a custom WinHTTP based web-server on Windows Server 2008 machine.
I pass "http://*:22222/" to HttpAddUrl
When I start my executable as Administrator or LocalSystem everything works fine. However if I try to run it as NetworkService to minimize security risks (since there are no legitimate reasons for the app to use admin rights) function fails with "Access Denied" error code.
I wasn't aware of NetworkService having any restrictions on which ports and interfaces it can listen on.
Is there a way to configure permissions in such a way so that I actually can run the app under NetworkService account and connect to it from other internet hosts?
You must be an administrator to add URLs to the http.sys URL mappings. Network Service does is not a member of the admin group, but the admnistrator's group and the System account are members.
IIS gets around this by having one process, inetinfo.exe, that runs as SYSTEM and sets up the URL mappings for worker processes (w3wp.exe) that run as Network Service.
Hope that clarifies tings.
Related
I'm trying to create a web app on AWS and I'm running into port issues. I would like to have multiple apps providing different services on different ports. I've created a website (on the same instance) to receive a text query and pass it to my app on port 3000. The app listening on 3000 is written in CherryPy.
We are using a VPN to provide security for the AWS instance. When logged into the VPN, everything works fine. The web page loads, the query returns the correct data. When I disconnect from the VPN, or someone else goes to the page, the page still loads, but queries to the service time out.
I've used netstat to make sure the service is listening but I'm not sure what could be blocking traffic. I've worked through the CORS issues as evident by the fact it works when I'm signed into the VPN.
What can I check now?
When I disconnect from the VPN, or someone else goes to the page, the page still loads, but queries to the service time out.
My assumption is that the web server and the app are on the same server.
It sounds very much like the connection from web server to app is happening via a routed IP address rather than localhost. In addition to being slower, it's also hitting your firewall rules.
Configure the web server to access your app on localhost:3000 and the issue should clear up.
I actually got it working. I have an AWS instance with nginix and CherryPy. When the user goes to a web address, the nginix page loads with a form for a query string. When they submit a string, the string is POSTed to a CherryPy service running on port 3000. The CherryPy service does some computations and returns a result via JSON.
I thought I had opened up everything completely for testing, but I was having so many issues. It turned out that having CherryPy set
"Access-Control-Allow-Origin" = "*"
wasn't working, instead I needed to specifically set the origin of the calling page.
I have Shibboleth configured on an IIS server and am using it protect a .NET application.
I need authenticated access for users accessing the application over the web and for that Shibboleth is working fine.
The application also hosts web services which need to be accessed by other applications in the same server and for that working with Shibboleth is a challenge since web service clients cannot deal with the log in page.
Is it possible to configure Shibboleth to ignore requests coming from the same server for example by checking the IP address?
It won't directly answer your question, but I can share a workaround I found and hope it can help with your problem too.
Define another website in IIS pointing to the same folder as the initial one, and make it only respond to a different domain (like something.local). Then in IP Address and Domain Restrictions, make sure only 127.0.0.1 is allowed to access it.
In C:\Windows\System32\drivers\etc open the file "hosts" in Notepad (running with Administrator privileges). Add the line "127.0.0.1 something.local" (no quotes; make sure the domain is the same one you defined before)
Now, make the webservices call the application by the new domain.
I apologize in advance if the question is ridiculous.
I have an asmx service running in Azure (HTTP - no SSL).
I have a WPF app that loads a X509Certificate2 and adds it to the request by doing the following:
X509Certificate2 cert = new X509Certificate2("...");
webRequest.ClientCertificates.Add(cert);
In the web service I get the certificate by
new X509Certificate2(this.Context.Request.ClientCertificate.Certificate)
And then I load a cert (that I have both uploaded to the Azure control panel and added to my service definition file) by using the following sample:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, certName, true);
And then I validate by doing the following:
clientCert.Thumbprint == certs[0].Thumbprint
Now unfortunately I get an exception (System.Security.Cryptography.CryptographicException: m_safeCertContext is an invalid handle) as soon as I do
Request.ClientCertificate.Certificate
So I have a few questions. How do I avoid the exception. This answer states I need to modify an IIS setting, but how can I do that in Azure?
In any case is this even the proper way to do certificate authentication?
Thanks!
You can use command scripts to modify IIS, in combination with appcmd.exe.
For a quick example (disabling timeout in an application pool), take a look at this sample by Steve Marx.
In this example, you'd call DisableTimeout.cmd as a startup task. For more info on creating startup tasks, you can watch this episode of Cloud Cover Show. There should be a lab on startup tasks in the Platform Training Kit as well.
Just remember that any type of IIS configuration change should be made via an automated task at startup. If you manually change IIS via RDP, those changes won't propagate to all of your instances, and won't remain persistent in the event of hardware failure or OS update.
You can remote into your azure instances to manage IIS. As for a way to do it globally for all instances at once, I'm not sure. That would be an interesting side project though.
http://learn.iis.net/page.aspx/979/managing-iis-on-windows-azure-via-remote-desktop/
Using the Windows HTTP API I'm running a HTTP file server on localhost.
This involves calling HttpAddUrl(hRequestQueue, L"http://localhost:80/", NULL).
This fails with ERROR_ACCESS_DENIED unless the user runs the application as administrator. I need this functionality for users who don't have admin privileges. (What's wrong with a user running a localhost server anyway? It's just for the user themselves.)
I found a hotfix for Vista and XP which seems aimed at solving this, but there's nothing for Windows 7. The article implies it was fixed in Vista SP1, and I have Windows 7 SP1 and it's still a problem - did the fix not make it to Windows 7?
Is there anything else I can do to get the server to run for non-admins?
Answering my own question, but found a workaround: the IANA port numbers state ports 49152-65535 are for dynamic/private purposes. HttpAddUrl for localhost on a port >= 49152 works fine for non-admins.
This must be configured on system level because HTTP API uses http.sys (kernel driver). You can use netsh.exe command executed with Administrator privileges to grant access to the user or application:
netsh http add urlacl url=http://localhost:80/ user=EVERYONE listen=yes delegate=no
Ports 1-1024, by default, require administrative access. Otherwise you get error code 5 (ACCESS_DENIED). If you attempt to bind to a port above 1024, e.g.:
http://localhost:8080/
it will work for non-admin users. In your case you tried to listen on port 80, which HttpServer API limits to administrators.
Everything in Windows is controlled by Access Control Lists (ACLs); this includes the listen ports allowed when using HttpServer. You can display the current ACLs used by http by running:
>netsh http show urlacl
If you do that, you'll see a lot of ACLs already defined by various systems.
Windows Communication Foundation
One ACL entry is particularly interesting:
Reserved URL : http://+:80/Temporary_Listen_Addresses/
User: \Everyone
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;WD)
Everyone is granted the right to listen on port 80, as long as you live off of:
/Temporary_Listen_Addresses/
This url is used by Windows Communication Foundation (WCF), which normally constructs a URL of the form:
http://+:80/Temporary_Listen_Addresses/{random-guid}/
It also means, if you really want port 80, you can listen with your own, for example:
http://localhost:80/Temporary_Listen_Addresses/64E3DCC6-FE47-4A86-87F4-48D2E1B44AE9/
As long as nobody is already using port 80 (i'm looking at your Skype!), you'll get it.
WinSock listening sockets do not require admin
While the HttpServer API has ACLs controlling access to ports below 1024, it should be noted that the WinSock API has no restriction.
If you want to use WinSock to open a listening socket on port 80, you do not need to be an administrator. It is only the Http api that has the ACL.
I have a web service running under IIS7 on a server with a host header set so that it receives requests made to http://myserver1.mydomain.com.
I've set Windows INtegrated Authentication to Enabled and everything else (basic, anonymous, etc) to Disabled.
I'm testing the web service using a powershell script, and it works fine when I run it from my workstation against http://myserver1.mydomain.com
However, when I run the same exact script on the IIS server itself, I get a 401-Unauthorized message.
In addition, I've tried installing the web service on a second server, myserver2.mydomain.com. Again I can call my test script fine from BOTH my workstation and from myserver1.
So it seems the only issue is when the client is on the same box as the web server itself - somehow the windows credentials are not being passed or recognized.
I tried playing with IE settings on myserver1 (checked and unchecked 'Enable Windows Integrated Authentication', and added the URL to Local Sites). That did not seem to have an effect.
When I look at the IIS logs, I see the 401 unauthorized line but very little other information.
I see basically the same behavior when testing with IE (v9) - works from my workstation but not when IE is running on the IIS server.
I found the answer after several hours:
By default, there is something called a LoopbackCheck which will reject windows authentication if the host header used for the site does not match the local host's name. This behavior will only be seen when the client is on the local host. The check is there to defeat possible reflection attacks.
More details here:
http://support.microsoft.com/kb/896861
The kb item discusses ways to disable the Loopback check, but I ended up just switching from using host headers to ports to distinguish the different sites on the IIS server.
Thanks to those who gave assistance.
Try checking the actual credential that is being passed when you are running on the server itself. Often times you will be running on some system account that doesn't have access to the resource in question.
For example, on your box your credentials are running as...
MYDOMAIN\MYNAME
and the server will be something like...
SYSTEM\SYSTEM_ACCOUNT
and so this will fail because 'SYSTEM\SYSTEM_ACCOUNT' doesn't have credentials.
If this is the case, you can fix the problem in one of two ways.
Give 'SYSTEM\SYSTEM_ACCOUNT' access to the resource in question. Most people would avoid this strategy due to security concerns (which is why the account has no access in the first place).
Impersonate, or change the credentials of the client manually to something that does have access to the resource, 'MYDOMAIN\MYNAME' for example. This is what most people would probably go with, including myself.