Not Just VPN: How It Was and Where It's Going

We take a service that accepts requests (in our case :80) and redirects them to habr.com:443

const (
	urlOld  = "habr.com"
	urlNew  = "habr-test.yandex.tel"
	portRun = "80"
)

We will use standard libraries as tools and for simplicity we will also take gin

import (
	"io"
	"net/http"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"
)

In the main function, we will create our web server, which will listen to all requests, and we will forward our entire received path to remoteUrl in fetchRemoteContent and return the received result to the client.

func main() {
	r := gin.Default()
	r.Any("/*proxyPath", func(c *gin.Context) {
		proxyPath := c.Param("proxyPath")

		remoteUrl := "https://" + urlOld + proxyPath
		remote, err := url.Parse(remoteUrl)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid URL"})
			return
		}

		// Делаем запрос к удаленному серверу для получения содержимого
		content, contentType, headers, err := fetchRemoteContent(remote.String(), c.Request)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch remote content"})
			return
		}

		// прокидываем заголовки ответа удаленного сервера
		for key, values := range headers {
			for _, value := range values {
				c.Writer.Header().Add(key, value)
			}
		}

		c.Data(http.StatusOK, contentType, content)
	})

	r.Run(":" + portRun)
}

And what are we going to do in the client? Actually, everything is the same as what came to us:

  • Let's create a Request with the parameters that came to us

  • Let's throw in the headlines

  • Let's make a request

  • We subtract the answer

  • Let's change the text content

  • If there was a redirect, we will process it correctly

  • And return the result from the function

func fetchRemoteContent(remoteUrl string, originalRequest *http.Request) ([]byte, string, http.Header, error) {
	client := &http.Client{}

	req, err := http.NewRequest(originalRequest.Method, remoteUrl, originalRequest.Body)
	if err != nil {
		return nil, "", nil, err
	}

	for key, values := range originalRequest.Header {
		for _, value := range values {
			req.Header.Add(key, value)
		}
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, "", nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, "", nil, err
	}

	contentType := resp.Header.Get("Content-Type")
	if isTextContent(contentType) {
		body = []byte(strings.ReplaceAll(string(body), urlOld, urlNew))
	}

	if location := resp.Header.Get("Location"); location != "" {
		if strings.HasPrefix(location, "https://"+urlOld) {
			resp.Header.Set("Location", strings.Replace(location, urlOld, urlNew, 1))
		}
	}

	resp.Header.Del("Content-Length")

	return body, contentType, resp.Header, nil
}

And in order not to clutter the code, we will take out the processing of content types, where we will change the content

func isTextContent(contentType string) bool {
	textTypes := []string{
		"text/html",
		"application/javascript",
		"application/json",
		"text/plain",
		"application/xml",
		"text/css",
		"application/xhtml+xml",
	}

	for _, t := range textTypes {
		if strings.Contains(contentType, t) {
			return true
		}
	}
	return false
}

So, you can see the working prototype here = https://habr-test.yandex.tel/ru/articles/790828/

And here is ours, already another Habr

Basic functionality works. Including SSL

Basic functionality works. Including SSL

And why do we need this?

But this was all in an attempt to explain what kind of potentially unlimited black hole of the Runet may await us in the near future.

After all, YouTube is already slowing down, network protocols are being blocked, corporate VPNs and services are being whitelisted. Which leads to an even greater reduction in overall protection and ordinary users missing all warnings.

Here are just the most popular types of fraud, the number of which increases every day.

  1. Increasing number of phishing
    For example, you noticed that anyone can buy a second-level domain yandex. {{any of the modern zones}} , host mail on Yandex360, host a server on YandexCloud and send targeted phishing emails on behalf of Yandex. I'm sure half of the information security specialists won't be able to tell the difference between this and phishing, not to mention regular PC users.

  2. Man-in-the-Middle Attack -> read here

  3. Telephone scammers and another type of old “scam” using simply new info-reasons

Prohibitions never help, but only delay the onset of the problem.
It would be interesting to discuss this together in the comments.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *