How to pass our client request through Authorized upstream proxy to specific web address ?
I have to enter username/password to connect an upstream proxy and then open some web page in my browser (for example jj.com) in HTTP and HTTPS protocol (I can set that in Firefox manual proxy options).
So I want make a way to get access for other client to open jj.com whitout need to know and enter username/password and open web page (like jj.com) in her/his browser through NginX.
+--------------------+ +---------------------+
| | | upstramProxy:9090 | +----------+
| Client browser | | user:user-003 |+----->| jj.com |
| | | pass:123456 |<------+----------+
+--------------------+ +---------------------+
| ^ (myProxyService.com:8080/pr?url=jj.com) | ^
| | | |
| | | |
| | +---------------------+
| +--------------------------------| myProxyService.com |
| | NginX in myServer |
+---------------------------------->| Listen to 8080 |
+---------------------+
Is it possible ?
If there is any other approach I want to know.
Simple java web application in witch java send all request through third party proxy named : myProxyServer
public static void processRequest(HttpServletRequest req, HttpServletResponse resp) {
try {
PrintWriter out = resp.getWriter();
System.out.println(req.getRequestURI());
System.out.println(req.getRequestURL());
jjTools.ShowAllParameter(req);
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("thirdpartyProxy.com", 8080),
new UsernamePasswordCredentials("username", "passss".toCharArray())
);
try (final CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider).build()) {
final HttpHost target = new HttpHost("https", "www.targetwebSite.com", 443);
final HttpHost proxy = new HttpHost("http", "thirdpartyProxy.com", 8080);
final RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.setCircularRedirectsAllowed(true)
.build();
final HttpGet httpget = new HttpGet(req.getRequestURI().replaceFirst("/My_Proxy/", "/"));
httpget.setConfig(config);
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri()
+ " via " + proxy);
try (final CloseableHttpResponse response = httpclient.execute(target, httpget)) {
System.out.println("----------------------------------------");
resp.setContentType(response.getHeader("Content-Type").toString());
System.out.println(response.getHeader("Content-Type").toString());
System.out.println(response.getCode() + " " + response.getReasonPhrase());
out.print(EntityUtils.toString(response.getEntity())+"<scipt>alert");
}
}
out.close();
} catch (Exception ex) {
Logger.getLogger(Listener.class.getName()).log(Level.SEVERE, null, ex);
}
}
Then you have to config nginX.conf like the code below:
server {
listen 80;
server_name targetwebSite.localhost;
location / {
#proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Server $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/My_Proxy/;
}
}
And for result it will be working for all page with its CSS and JavaScript files in
http : / / targetwebSite.localhost /
address
note: It have some problem with cookie and accept cookie policies in browser
https://www.tutorialspoint.com/apache_httpclient/apache_httpclient_using_proxy.htm
Related
I trying to enable websocket on production environment without success.
In dev, locally everything start working after 5 minutes, but on prod with nginx+tomcat+CF I have a problem
Connection closed in a second
Chrome
FireFox
I see problems during connection, but can't fix it.
The setup is:
cloudflare with certificate termination (Tested without proxifying, same result)
nginx on app server
tomcat 8.5
Grails 4.0.13
The setup is very basic:
$(function() {
var socket = new SockJS("/stomp");
var client = webstomp.over(socket);
client.connect({}, function() {
client.subscribe("/topic/hello", function(message) {
$("#helloDiv").append("ALL:"+message.body);
});
$("#helloButton").click(function() {
client.send("/app/hello", JSON.stringify("world"));
});
});
java config with one custom line:
#CompileStatic
#Configuration
#EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
messageBrokerRegistry.enableSimpleBroker "/queue", "/topic"
messageBrokerRegistry.setApplicationDestinationPrefixes "/app"
}
#Override
void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
// ######custom code, to avoid 403 with https
stompEndpointRegistry.addEndpoint("/stomp").setAllowedOrigins("*")
stompEndpointRegistry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS()
}
#Bean
GrailsSimpAnnotationMethodMessageHandler grailsSimpAnnotationMethodMessageHandler(
SubscribableChannel clientInboundChannel,
MessageChannel clientOutboundChannel,
SimpMessageSendingOperations brokerMessagingTemplate
) {
def handler = new GrailsSimpAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate)
handler.destinationPrefixes = ["/app"]
return handler
}
#Bean
GrailsWebSocketAnnotationMethodMessageHandler grailsWebSocketAnnotationMethodMessageHandler(
SubscribableChannel clientInboundChannel,
MessageChannel clientOutboundChannel,
SimpMessageSendingOperations brokerMessagingTemplate
) {
def handler = new GrailsWebSocketAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate)
handler.destinationPrefixes = ["/app"]
return handler
}
build.gradle
implementation "org.grails.plugins:grails-spring-websocket:2.5.0.RC1"
implementation platform("io.netty:netty-bom:4.1.79.Final")
implementation platform("io.projectreactor:reactor-bom:Californium-SR6")
implementation "io.netty:netty-all"
implementation "io.projectreactor.netty:reactor-netty"
nginx-app
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
....
location /stomp/ {
proxy_pass http://upstr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
Any ideas in what direction should I dig?
UPDATE
Same thing without https-wss
I followed the way suggested in this StackOverflow comment
location / {
content_by_lua_block {
-- some logic here
if flag then
return ngx.exec("#http1_0")
end
return ngx.exec("#http1_1")
}
}
location #http1_0 {
proxy_pass ...;
proxy_http_version 1.0;
...
}
location #http1_1 {
proxy_pass ...;
proxy_http_version 1.1;
...
}
But I am getting the following error:
kong_1 | 2020/11/10 17:19:33 [error] 25#0: 37490 failed to run balancer_by_lua: /usr/local/share/lua/5.1/kong/init.lua:576: attempt to index local 'balancer_data' (a nil value)
kong_1 | stack traceback:
kong_1 | /usr/local/share/lua/5.1/kong/init.lua:576: in function 'balancer'
I want to change the proxy http version in Lua code programmatically. Is there any way?
I'm trying to use a simple HTTP proxy to externally cache the responses. I tried the following snippet:
public static void main(String[] args) {
HttpClient httpClient = HttpClient.builder().options(httpOptions -> {
httpOptions.proxy(proxyOptions -> proxyOptions
.type(Proxy.HTTP)
.address(InetSocketAddress.createUnresolved("localhost", 7000))
);
}).build();
String url = "http://httpbin.org/get";
HttpClientResponse response = httpClient.get(url).block();
System.out.println(response == null ? "null" : response.status().code());
}
... but the result is that the client starts with a CONNECT command, creating a TCP tunnel.
When I work with curl, I do the following:
curl "http://httpbin.org/get" -x "localhost:7000"
... and it simply issues a regular HTTP request against the proxy.
My question: how do I use Raector-Netty to issue a regular (not a CONNECT based) request against a proxy?
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(options ->
options.httpProxy(addressSpec -> {
return addressSpec.host("http://proxy_server").port(proxy_port); }));
webClient = WebClient.builder()
.clientConnector(connector)
.baseUrl(baseUrl)
.build();
I have recently been trying to setup port mapping for my game. This is to make one of the players be the host. For that I need the player to open port 7777.
If there is a match already on it will simply join it. If it doesn't find empty matches it will simply make one. And If it fails to make one it will wait until someone makes one and join it.
Therefor I need to be able to use something like UPnP to portmap my port. I also need to be able to catch errors to see wheter to proceed with creation of a match or to simply wait for one and join.
I am currently working in the Unity game engine which uses .NET 2.0. This makes me very limited as Open.NAT isn't compatible. I tried Mono.NAT but I can't get it working.
Does anyone have any suggestions of how I should approach this? What libraries to use and maybe even provide me with code snippets to get me started.
Thanks, TwoTen.
Edit1: The current Mono.NAT code looks like this:
private void DeviceFound(object sender, DeviceEventArgs args)
{
Debug.Log("1");
INatDevice device = args.Device;
Debug.Log("2");
Mapping map = new Mapping(Protocol.Tcp, 6699, 6699);
Debug.Log("3");
device.CreatePortMap(map);
Debug.Log("4");
int test = device.GetAllMappings().Length;
Debug.Log(test);
foreach (Mapping portMap in device.GetAllMappings())
{
Debug.Log("5");
Debug.Log(portMap.ToString());
}
}
private void DeviceLost(object sender, DeviceEventArgs args)
{
INatDevice device = args.Device;
Mapping map = new Mapping(Protocol.Tcp, 6699, 6699);
device.DeletePortMap(map);
}
I The last debug statement that is called is number 4. I the port does not get opened and no excetion is thrown either.
What am I doing wrong?
Also, In my start function I call this:
NatUtility.DeviceFound += DeviceFound;
NatUtility.DeviceLost += DeviceLost;
NatUtility.StartDiscovery();
I have found an answer on how to successfully. I dropped Mono.NAT and instead went with Open.NAT which has been ported to .NET 3.5 which is compatible with Unity!
The final code I ended up using looks like this:
private static Task Test()
{
var nat = new NatDiscoverer();
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
NatDevice device = null;
var sb = new StringBuilder();
IPAddress ip = null;
return nat.DiscoverDeviceAsync(PortMapper.Upnp, cts)
.ContinueWith(task =>
{
device = task.Result;
return device.GetExternalIPAsync();
})
.Unwrap()
.ContinueWith(task =>
{
ip = task.Result;
sb.AppendFormat("\nYour IP: {0}", ip);
return device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 7777, 7777, 0, "myGame Server (TCP)"));
})
.Unwrap()
.ContinueWith(task =>
{
return device.CreatePortMapAsync(
new Mapping(Protocol.Udp, 7777, 7777, 0, "myGame Server (UDP)"));
})
.Unwrap()
.ContinueWith(task =>
{
sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip);
sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+");
sb.AppendFormat("\n| PORT | PUBLIC (Reacheable) | PRIVATE (Your computer) | Description | |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
sb.AppendFormat("\n| | IP Address | Port | IP Address | Port | | Expires |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
return device.GetAllMappingsAsync();
})
.Unwrap()
.ContinueWith(task =>
{
foreach (var mapping in task.Result)
{
sb.AppendFormat("\n| {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|",
ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description,
mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime());
}
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
sb.AppendFormat("\n[Removing TCP mapping] {0}:1700 -> 127.0.0.1:1600", ip);
return device.DeletePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700));
})
.Unwrap()
.ContinueWith(task =>
{
sb.AppendFormat("\n[Done]");
Debug.Log(sb.ToString());
});
}
All I had to do was to do this in my start function:
Test().Wait();
The router registers the port and opens it. HOWEVER. The website canyouseeme.org FAILED to see the port as open for what ever reason. To verify that it was registered I went into my router settings and looked for UPnP. There was then a list of applications including mine. I am yet to do real world tests but I will update the post once those have been made.
The Open.NAT version compatible with Unity was found here:
Edit: I have now performed real world tests. Everything is working and users can connect without relay and or unitys matchmaking servers
I'm trying to redirect any HTTP requests to my server over to HTTPS.
ELB is listening on port 80 and forwarding all request to port 8088 on my application. The application then sends a 301 Moved Permanently response redirecting to the same URL, but with any ports stripped off and 'https://' prepended. This causes clients to re-request the url over HTTPS.
When I test it locally it works fine, but when I deploy it to EC2 behind an Elastic Load Balancer I get 502 Bad Gateway coming back. The server is receiving the request and appears to be sending the redirect correctly (as I said, it works when I hit the server directly, not via a load balancer).
It turns out that ELB is very picky about what it considers a 'valid' response and will return 502 Bad Gateway if it isn't happy. I fixed it by making sure the response from my server had the following headers:
eg. if I was listening at http://example.com
I send back the following response:
HTTP/1.1 301 Moved Permanently
Content-Type: */*; charset="UTF-8"
Location: https://example.com/
Content-Length: 0
This makes ELB happy and everything works.
For interest, here's the code (Java, using Simpleframework):
private static void startHttpsRedirector() throws IOException {
org.simpleframework.http.core.Container container = new org.simpleframework.http.core.Container() {
#Override
public void handle(Request request, Response response) {
Path path = request.getPath();
Query query = request.getQuery();
String rawHost = request.getValue("host");
System.out.println("Raw host: " + rawHost);
System.out.println("Raw path: " + path);
System.out.println("Raw query: " + query);
String host = rawHost.replaceFirst("\\:.*", "");
response.setStatus(Status.MOVED_PERMANENTLY);
String redirectTo = "https://" + host + path + (query.values().size() > 0 ? "?" + query : "");
System.out.println("redirectTo = " + redirectTo);
response.setContentType("*/*; charset=\"UTF-8\"");
response.setValue("Location", redirectTo);
response.setContentLength(0);
try {
response.commit();
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Server server = new ContainerServer(container);
Connection connection = new SocketConnection(server);
SocketAddress address = new InetSocketAddress(8088);
connection.connect(address);
}
The same code in javascript can be found here: https://gist.github.com/dhobbs/6164710