lighttpd configuration to proxy/rewrite from one domain to another - mod-rewrite

i need to setup proxy/rewrite on lighttpd!
i have server1, which serves via http 2 different web app paths:
* http://server1/path1
* http://server1/path2
also, i have lighttpd server in front of server1
i want to setup rewriting and/or proxing on lighttpd, so that each of the 2 paths would be served as root path on different domains:
* requests to http://server2.com/* are proxied/rewrited to http://server1/path1/*
* requests to http://server3.com/* are proxied/rewrited to http://server1/path2/*
important:
server2.com and server3.com can access server1 only via http
redirects are not the option, users of server2.com & server3.com shouldn't not know that the actual web apps are served from different paths of server1.
Is it possible?

Your need is known by lighttpd developers from several years.
It is answered by a workaround or new feature depending on the version.
Lighttpd 1.4
A workaround is explained in the bugtracker : bug #164
$HTTP["url"] =~ "(^/path1/)" {
proxy.server = ( "" => ("" => ( "host" => "127.0.0.1", "port" => 81 )))
}
$SERVER["socket"] == ":81" {
url.rewrite-once = ( "^/path1/(.*)$" => "/$1" )
proxy.server = ( "" => ( "" => ( "host" => "server2.com", "port" => 80 )))
}
Lighttpd 1.5
They added this feature with this command (official documentation) :
proxy-core.rewrite-request : rewrite request headers or request uri.
$HTTP["url"] =~ "^/path1" {
proxy-co...
proxy-core.rewrite-request = (
"_uri" => ( "^/path1/?(.*)" => "/$1" ),
"Host" => ( ".*" => "server2.com" ),
)
}

Update: lighttpd 1.4.46 (released in 2017) introduced proxy.header which can perform limited URL-prefix rewriting. More info at lighttpd mod_proxy

Related

Create a seperate HTTPS site on lighttpd?

I'm running lighttpd on a Raspbian Pi3 Model B that serves as the HTTP webserver for Pi-Hole, a DNS based adblocker, running on port 80.
I'd like to also have lighttpd listen on port 443 for HTTPS requests, but have it direct to a completely different HTML file instead of Pi-Hole.
How can I do this (using a self-signed SSL certificate)?
This can be done with mod_proxy.
Add mod_proxy too your list of included modules in lighttpd.conf i.e:
server.modules = (
"mod_proxy"
)
Then you can redirect requires to 443 (https) somewhere else.
$SERVER["socket"] == ":443" {
proxy.server = (
"" => ((
"host" => "127.0.0.1",
"port" => "8080"
))
)
}

Having issues running a script via cgi in lighttpd

I have the following piece in my config file:
cgi.assign = ( ".sh" => "" )
$HTTP["url"] =~ "^/urlpath/" {
$HTTP["querystring"] =~ "cams=on" {
cgi.assign = ( "" => "/scriptpath/CamsOn" )
}
$HTTP["querystring"] =~ "cams=off" {
cgi.assign = ( "" => "/scriptpath/CamsOff" )
}
url.redirect = ( "^/urlpath/" => "http://somewebsite" )
}
I have the cgi module loaded:
server.modules = (
"mod_redirect",
"mod_access",
"mod_cgi",
"mod_accesslog" )
Now "CamsOn" and "CamsOff" are shebanged shell scripts. To be honest I had done this before and had it working but my server crashed and I lost my configs. For some reason I can't figure for the life of me how to get it working. I do the redirect so I don't have to actually create the "urlpath" page. The redirect works fine inside the $HTTP["url"] piece, and I've even tested the querystring portion by nesting a redirect inside that just takes it to google.com; urlpath/?cams=on sent me to google accordingly.
What am I doing wrong?
Update:
I was to get it to work using
$HTTP["url"] =~ "^/urlpath/" {
$HTTP["querystring"] =~ "cams=on" {
cgi.assign = ( "" => "/scriptpath/CamsOn" )
}
$HTTP["querystring"] =~ "cams=off" {
cgi.assign = ( "" => "/scriptpath/CamsOff" )
}
}
I'm thinking that the redirect was getting parsed first, so when the address changed, it no longer fit the URL and querystring comparisons. Can I change this? The idea is to make the urlpath dynamic and updated in the conf file dynamically. This is why I have the redirect send you to another address. This way I also don't need to do html editing or create additional folders.
What am I doing wrong?
a) did not make backups
b) did not make backups
c) did not make backups
d) did not look in your own stackoverflow post history
See Can't figure out how to receive http requests using lighttpd
If you want to reduce the number of places you edit in your config file, you can assign a value to a variable in lighttpd.conf and use the variable in lighttpd.conf. See var.* in
https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_Configuration
var.camsurlpath = "/urlpath/"
$HTTP["url"] =~ "^" + var.camsurlpath {
...
}

Creating an ALIAS record on Route 53 using ruby sdk

I'm trying to programmatically create a Route 53 CNAME record using the ALIAS settings with the ruby aws-sdk gem.
I can't find a way of doing this in the documentation. I see how to create a record itself but not how I would create an ALIAS one.
rrsets = AWS::Route53::HostedZone.new(hosted_zone_id).rrsets
rrset = rrsets.create('foo.example.com.', 'CNAME', :ttl => 300, :resource_records => [{:value => 'foo.example.com.s3.amazon.weast.uk'}])
Below is an example of how you would alias to a S3 Web Site Endpoint in US-WEST-2.
$irb
irb> require 'aws-sdk'
irb> rrsets = AWS::Route53::HostedZone.new('Z1234').rrsets #replace Z123 with your hosted zone in which you are creating the record.
irb> rrset = rrsets.create('foo.example.com.', 'A', :alias_target => {:hosted_zone_id => 'Z3BJ6K6RIION7M', :dns_name => 's3-website-us-west-2.amazonaws.com' , :evaluate_target_health => false }) # Z3BJ6K6RIION7M is the target hosted zone, in this case Z3BJ6K6RIION7M and can be obtained from the below link, if it's s3.
Endpoints & Hosted Zone Ids:
http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
Note: Alias records can not have TTLs and require target hosted zone ids. The reason they don't have TTLs is that they use the target's TTL.

Mod rewrite for opencart in lighttpd

These are the rules in lighttpd.conf
$HTTP["host"] =~ "^(www\.)?mysite.com" {
url.rewrite-once = ( "^/$" => "/index.php?route=common/home" )
url.rewrite-if-not-file = ( "^/(.*)" => "/index.php?_route_=$1" )
url.access-deny = ( ".tpl", ".ini", ".log" )
server.error-handler-404 = "/index.php?route=error/not_found"
index-file.names = ( "index.php" )
}
Everything works fine. When i open www.mysite.com/adidas it works, but when i try to open www.mysite.com/adidas?page=2 it gives me error404.
And when i try to open www.mysite.com/admin it gives me again error404, but when i open www.mysite.com/admin/index.php it works...
How can i fix it..
Found this article which seems to answer your first issue. For the admin issue, I'm assuming you need to at least use /admin/ including the second forward slash

Is there a way to attach Ruby Net::HTTP request to a specific IP address / network interface?

Im looking a way to use different IP addresses for each GET request with standard Net::HTTP library. Server has 5 ip addresses and assuming that some API`s are blocking access when request limit per IP is reached. So, only way to do it - use another server. I cant find anything about it in ruby docs.
For example, curl allows you to attach it to specific ip address (in PHP):
$req = curl_init($url)
curl_setopt($req, CURLOPT_INTERFACE, 'ip.address.goes.here';
$result = curl_exec($req);
Is there any way to do it with Net::HTTP library? As alternative - CURB (ruby curl binding). But it will be the last thing i`ll try.
Suggestions / Ideas?
P.S. The solution with CURB (with dirty tests, ip`s being replaced):
require 'rubygems'
require 'curb'
ip_addresses = [
'1.1.1.1',
'2.2.2.2',
'3.3.3.3',
'4.4.4.4',
'5.5.5.5'
]
ip_addresses.each do |address|
url = 'http://www.ip-adress.com/'
c = Curl::Easy.new(url)
c.interface = address
c.perform
ip = c.body_str.scan(/<h2>My IP address is: ([\d\.]{1,})<\/h2>/).first
puts "for #{address} got response: #{ip}"
end
I know this is old, but hopefully someone else finds this useful, as I needed this today. You can do the following:
http = Net::HTTP.new(uri.host, uri.port)
http.local_host = ip
response = http.request(request)
Note that you I don't believe you can use Net::HTTP.start, as it doesn't accept local_host as an option.
There is in fact a way to do this if you monkey patch TCPSocket:
https://gist.github.com/800214
Curb is awesome but won't work with Jruby so I've been looking into alternatives...
Doesn't look like you can do it with Net:HTTP. Here's the source
http://github.com/ruby/ruby/blob/trunk/lib/net/http.rb
Line 644 is where the connection is opened
s = timeout(#open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
The third and fourth arguments to TCPSocket.open are local_address and local_port, and since they're not specified, it's not possible. Looks like you'll have to go with curb.
Of course you can. I did as below:
# remote_host can be IP or hostname
uri = URI.parse( "http://" + remote_host )
http = Net::HTTP.new( uri.host, uri.port )
request = Net::HTTP::Get.new(uri.request_uri)
request.initialize_http_header( { "Host" => domain })
response = http.request( request )

Resources