Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
obfs4portscan
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Legacy
gitolite
user
phw
obfs4portscan
Commits
262dbdc6
Unverified
Commit
262dbdc6
authored
5 years ago
by
Philipp Winter
Browse files
Options
Downloads
Patches
Plain Diff
Initial import of source code.
parent
37254249
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
handlers.go
+78
-0
78 additions, 0 deletions
handlers.go
html.go
+81
-0
81 additions, 0 deletions
html.go
main.go
+88
-0
88 additions, 0 deletions
main.go
with
247 additions
and
0 deletions
handlers.go
0 → 100644
+
78
−
0
View file @
262dbdc6
package
main
import
(
"fmt"
"golang.org/x/time/rate"
"net"
"net/http"
"time"
)
// limiter implements a rate limiter. We allow 1 request per second on average
// with bursts of up to 5 requests per second.
var
limiter
=
rate
.
NewLimiter
(
1
,
5
)
// Index returns the landing page (which contains the scanning form) to the
// user.
func
Index
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
fmt
.
Fprintln
(
w
,
IndexPage
)
}
// SendResponse sends the given response to the user.
func
SendResponse
(
w
http
.
ResponseWriter
,
response
string
)
{
w
.
Header
()
.
Set
(
"Content-Type"
,
"text/html; charset=utf-8"
)
w
.
WriteHeader
(
http
.
StatusOK
)
fmt
.
Fprintln
(
w
,
response
)
}
// ScanDestination extracts the given IP address and port from the POST
// parameters, triggers TCP scanning of the tuple, and returns the result.
func
ScanDestination
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// We implement rate limiting to prevent someone from abusing this service
// as a port scanner.
if
limiter
.
Allow
()
==
false
{
SendResponse
(
w
,
"Rate limit exceeded. Wait for a bit."
)
return
}
// The number of seconds we're willing to wait until we decide that the
// given destination is offline.
timeout
,
_
:=
time
.
ParseDuration
(
"3s"
)
r
.
ParseForm
()
// These variables will be "" if they're not set.
address
:=
r
.
Form
.
Get
(
"address"
)
port
:=
r
.
Form
.
Get
(
"port"
)
if
address
==
""
{
SendResponse
(
w
,
"No address given."
)
return
}
if
port
==
""
{
SendResponse
(
w
,
"No port given."
)
return
}
portReachable
,
err
:=
IsTCPPortReachable
(
address
,
port
,
timeout
)
if
portReachable
{
SendResponse
(
w
,
SuccessPage
)
}
else
{
SendResponse
(
w
,
FailurePage
(
err
))
}
}
// IsTCPPortReachable returns `true' if it can establish a TCP connection with
// the given IP address and port. If not, it returns `false' and the
// respective error, as reported by `net.DialTimeout'.
func
IsTCPPortReachable
(
addr
,
port
string
,
timeout
time
.
Duration
)
(
bool
,
error
)
{
conn
,
err
:=
net
.
DialTimeout
(
"tcp"
,
fmt
.
Sprintf
(
"%s:%s"
,
addr
,
port
),
timeout
)
if
err
!=
nil
{
return
false
,
err
}
conn
.
Close
()
return
true
,
nil
}
This diff is collapsed.
Click to expand it.
html.go
0 → 100644
+
81
−
0
View file @
262dbdc6
package
main
import
(
"fmt"
)
// IndexPage contains the landing page of the service. It implements a simple
// form that asks for an IP address and TCP port.
var
IndexPage
=
`<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test your obfs4 bridge's TCP port</title>
</head>
<body>
<form method="POST" action="scan">
<h2>Tor bridge reachability test</h2>
<p>This service allows you to test if your obfs4 bridge is reachable to the
rest of the world.</p>
<p>Enter your bridge's IP address and obfs4 port, and click 'Scan'. The service
will then try to establish a TCP connection with your bridge and tell you
if it succeeded.</p>
<input type="text" required name="address" placeholder="IP address">
<input type="text" required name="port" placeholder="Obfs4 port">
<label ></label>
<button type="submit">Scan</button>
</form>
</body>
</html>
`
// SuccessPage is shown when the given address and port are reachable.
var
SuccessPage
=
`<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Success!</title>
</head>
<body>
<div align='center'>
<h2 style='color:green'>TCP port is reachable!</h2>
</div>
</body>
</html>
`
// FailurePage2 is shown when the given address and port are unreachable.
func
FailurePage
(
reason
error
)
string
{
var
failurePage1
=
`<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Failure!</title>
</head>
<body>
<div align='center'>
<h2 style='color:red'>TCP port is <i>not</i> reachable!</h2>
<tt>
`
var
failurePage2
=
`</tt>
</div>
</body>
</html>
`
return
fmt
.
Sprintf
(
"%s%s%s"
,
failurePage1
,
reason
,
failurePage2
)
}
This diff is collapsed.
Click to expand it.
main.go
0 → 100644
+
88
−
0
View file @
262dbdc6
package
main
import
(
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
)
type
Route
struct
{
Name
string
Method
string
Pattern
string
HandlerFunc
http
.
HandlerFunc
}
type
Routes
[]
Route
var
routes
=
Routes
{
Route
{
"Index"
,
"GET"
,
"/"
,
Index
,
},
Route
{
"ScanDestination"
,
"POST"
,
"/scan"
,
ScanDestination
,
},
}
// NewRouter creates and returns a new request router.
func
NewRouter
()
*
mux
.
Router
{
router
:=
mux
.
NewRouter
()
.
StrictSlash
(
true
)
for
_
,
route
:=
range
routes
{
var
handler
http
.
Handler
handler
=
route
.
HandlerFunc
handler
=
Logger
(
handler
,
route
.
Name
)
router
.
Methods
(
route
.
Method
)
.
Path
(
route
.
Pattern
)
.
Name
(
route
.
Name
)
.
Handler
(
handler
)
}
return
router
}
// Logger logs when we receive requests, and the execution time of handling
// these requests. We don't log client IP addresses or the given obfs4
// parameters.
func
Logger
(
inner
http
.
Handler
,
name
string
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
start
:=
time
.
Now
()
inner
.
ServeHTTP
(
w
,
r
)
log
.
Printf
(
"%s
\t
%s
\t
%s
\t
%s"
,
r
.
Method
,
r
.
RequestURI
,
name
,
time
.
Since
(
start
),
)
})
}
// main is the entry point of this tool.
func
main
()
{
if
len
(
os
.
Args
)
!=
3
{
fmt
.
Printf
(
"Usage: %s CERT_FILE KEY_FILE
\n
"
,
os
.
Args
[
0
])
os
.
Exit
(
1
)
}
certFile
:=
os
.
Args
[
1
]
keyFile
:=
os
.
Args
[
2
]
router
:=
NewRouter
()
log
.
Fatal
(
http
.
ListenAndServeTLS
(
":8080"
,
certFile
,
keyFile
,
router
))
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment