Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This guide provides detailed instructions for deploying Radius to various hostin
- [Heroku](#heroku)
- [Replit](#replit)
- [CodeSandbox](#codesandbox)
- [Yandex Cloud](#yandex-cloud)
- [Environment Variables](#environment-variables)
- [Troubleshooting](#troubleshooting)

Expand Down Expand Up @@ -123,6 +124,104 @@ docker-compose down
- Uses `docker-compose.yml` for orchestration
- Uses `.dockerignore` to exclude unnecessary files

### Yandex Cloud

**Prerequisites:**
- Yandex Cloud account
- Yandex Cloud CLI (optional for advanced deployment)

**Deployment via Compute Cloud (Virtual Machine):**

1. **Create a Virtual Machine:**
- Go to [Yandex Cloud Console](https://console.cloud.yandex.com/)
- Navigate to Compute Cloud → Virtual Machines
- Click "Create VM"
- Choose Ubuntu 22.04 LTS or later
- Select appropriate VM configuration (minimum 2 vCPU, 2 GB RAM recommended)
- Configure network settings and assign a public IP

2. **Connect to your VM:**
```bash
ssh <your-username>@<vm-public-ip>
```

3. **Install Node.js and npm:**
```bash
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
```

4. **Clone and deploy Radius:**
```bash
git clone https://github.com/RadiusProxy/Radius
cd Radius
npm install
npm run bstart
```

5. **Set up as a system service (optional):**
```bash
sudo nano /etc/systemd/system/radius.service
```

Add the following content:
```ini
[Unit]
Description=Radius Proxy Server
After=network.target

[Service]
Type=simple
User=<your-username>
WorkingDirectory=/home/<your-username>/Radius
ExecStart=/usr/bin/npm start
Restart=on-failure
Environment="PORT=8080"
Environment="NODE_ENV=production"

[Install]
WantedBy=multi-user.target
```

Enable and start the service:
```bash
sudo systemctl enable radius
sudo systemctl start radius
sudo systemctl status radius
```

**Deployment via Docker on Yandex Cloud:**

1. Install Docker on your Yandex Cloud VM:
```bash
sudo apt-get update
sudo apt-get install -y docker.io docker-compose
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
```

2. Clone and build:
```bash
git clone https://github.com/RadiusProxy/Radius
cd Radius
docker-compose up -d
```

**Using Yandex Object Storage for Static Assets (Optional):**

Radius can leverage Yandex Object Storage (S3-compatible) for serving static assets at scale:

1. Create an Object Storage bucket in Yandex Cloud Console
2. Configure bucket for public read access if needed
3. Set up environment variables for S3-compatible storage access

**Configuration for Yandex Cloud:**
- Ensure firewall rules allow traffic on port 8080 (or your configured port)
- Configure security groups to allow HTTP/HTTPS traffic
- Consider using Yandex Application Load Balancer for SSL termination
- Set up Yandex Cloud Monitoring for application health checks

## Environment Variables

All platforms support the following environment variables:
Expand Down Expand Up @@ -182,6 +281,22 @@ app.listen({ port: port, host: "0.0.0.0" })
- Ensure Docker daemon is running
- Check container logs: `docker logs <container-id>`

**Yandex Cloud:**
- Check VM firewall rules allow traffic on configured port
- Verify security group settings
- Check Node.js version compatibility: `node --version`
- Review application logs: `sudo journalctl -u radius -f`

### CAPTCHA Issues

**Issue:** reCAPTCHA, hCaptcha, or Yandex SmartCaptcha not loading
**Solution:**
- Radius now includes enhanced support for reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, and Yandex SmartCaptcha
- Ensure the proxy is properly configured and service workers are active
- Check browser console for any CORS or loading errors
- Verify that third-party cookies are not blocked in browser settings
- For Yandex SmartCaptcha, ensure proper API keys are configured in the parent application

## Additional Resources

- [Radius GitHub Repository](https://github.com/RadiusProxy/Radius)
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ If you can't donate, tell your friends about Radius!
[EpoxyTransport](https://github.com/MercuryWorkshop/EpoxyTransport) Bare-mux transport using epoxy-tls <br>
[CurlTransport](https://github.com/MercuryWorkshop/CurlTransport) Bare-mux transport using libcurl.js <br>

## Features
✅ **Enhanced CAPTCHA Support** - Full support for reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, and Yandex SmartCaptcha<br>
✅ **Multiple Proxy Engines** - Ultraviolet and Scramjet for maximum compatibility<br>
✅ **WebSocket Support** - Full support for real-time applications via Wisp<br>
✅ **Modern UI** - Clean, responsive interface built with TailwindCSS<br>
✅ **Easy Deployment** - Deploy to Heroku, Replit, Docker, Yandex Cloud, and more

# Setup
> [!TIP]
> Deploy localy on localhost to have a adress only you can acess, all of the functionaly will remain the same and the site will work properley! To do this, set up with (`pnpm`) using the staps below and visit http://localhost:8080 for a full conpleate site localy!
Expand Down
18 changes: 17 additions & 1 deletion public/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,33 @@ const sj = new ScramjetServiceWorker();

// Enhanced CAPTCHA and Cloudflare verification support
// List of CAPTCHA and verification domains that need special handling
// Supports reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, and Yandex SmartCaptcha
const CAPTCHA_DOMAINS = [
// Google reCAPTCHA domains
"google.com/recaptcha",
"www.google.com/recaptcha",
"recaptcha.net",
"www.recaptcha.net",
"gstatic.com/recaptcha",
"www.gstatic.com/recaptcha",
"google.com",
"gstatic.com",
// hCaptcha domains
"hcaptcha.com",
"newassets.hcaptcha.com",
"js.hcaptcha.com",
// Cloudflare Turnstile domains
"challenges.cloudflare.com",
"cloudflare.com/cdn-cgi/challenge",
"turnstile.cloudflare.com"
"turnstile.cloudflare.com",
// Yandex SmartCaptcha and Cloud domains
"smartcaptcha.yandexcloud.net",
"cloud.yandex.com",
"cloud.yandex.ru",
"api.cloud.yandex.net",
"storage.yandexcloud.net",
"yandex.com/showcaptcha",
"yastatic.net/s3/captcha-frontend"
];

// Helper function to check if URL is CAPTCHA-related
Expand Down
66 changes: 57 additions & 9 deletions src/utils/captcha-handler.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
/**
* Enhanced CAPTCHA and Cloudflare verification handler
* This module ensures that reCAPTCHA, hCaptcha, and Cloudflare Turnstile
* work seamlessly within the proxy environment
* Enhanced CAPTCHA and verification handler
* This module ensures that reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile,
* and Yandex SmartCaptcha work seamlessly within the proxy environment
*/

/**
* List of CAPTCHA and verification-related domains
* Enhanced to support reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, and Yandex SmartCaptcha
*/
const CAPTCHA_DOMAINS = [
"google.com",
// Google reCAPTCHA domains
"google.com/recaptcha",
"www.google.com/recaptcha",
"recaptcha.net",
"www.recaptcha.net",
"gstatic.com/recaptcha",
"www.gstatic.com/recaptcha",
"google.com",
"gstatic.com",
// hCaptcha domains
"hcaptcha.com",
"newassets.hcaptcha.com",
"js.hcaptcha.com",
// Cloudflare Turnstile domains
"cloudflare.com",
"challenges.cloudflare.com"
"challenges.cloudflare.com",
"turnstile.cloudflare.com",
// Yandex SmartCaptcha and Cloud domains
"smartcaptcha.yandexcloud.net",
"cloud.yandex.com",
"cloud.yandex.ru",
"api.cloud.yandex.net",
"storage.yandexcloud.net",
"yandex.com/showcaptcha",
"yastatic.net/s3/captcha-frontend"
];

/**
Expand All @@ -24,10 +44,16 @@ export function initializeCaptchaHandlers() {
if (typeof window === "undefined") return;

// Ensure global CAPTCHA callbacks are accessible
// Google reCAPTCHA
if (!window.___grecaptcha_cfg) {
window.___grecaptcha_cfg = { clients: {} };
}

// Yandex SmartCaptcha
if (!window.smartCaptcha) {
window.smartCaptcha = {};
}

// Monitor for CAPTCHA iframe creation and ensure proper setup
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
Expand All @@ -39,19 +65,27 @@ export function initializeCaptchaHandlers() {
src.includes("recaptcha") ||
src.includes("hcaptcha") ||
src.includes("challenges.cloudflare.com") ||
src.includes("turnstile")
src.includes("turnstile") ||
src.includes("smartcaptcha.yandexcloud.net") ||
src.includes("yandex.com/showcaptcha")
) {
// Ensure the iframe has proper sandbox permissions
if (node.sandbox && node.sandbox.length > 0) {
node.sandbox.add("allow-same-origin");
node.sandbox.add("allow-scripts");
node.sandbox.add("allow-forms");
node.sandbox.add("allow-popups");
}

// Ensure credentials are included for CAPTCHA cookies
if (node.getAttribute("credentialless") !== null) {
node.removeAttribute("credentialless");
}

// Set proper referrer policy for CAPTCHA requests
if (!node.referrerPolicy) {
node.referrerPolicy = "strict-origin-when-cross-origin";
}
}
}
});
Expand All @@ -73,6 +107,7 @@ export function initializeCaptchaHandlers() {

/**
* Enhance cookie handling to ensure CAPTCHA tokens are properly stored
* Supports reCAPTCHA, hCaptcha, Cloudflare Turnstile, and Yandex SmartCaptcha
*/
function enhanceCookieHandling() {
// Store original cookie descriptor
Expand All @@ -85,8 +120,16 @@ function enhanceCookieHandling() {
},
set(value) {
// Ensure SameSite=None for CAPTCHA cookies in cross-origin iframes
if (typeof value === "string" && value.includes("_GRECAPTCHA")) {
if (!value.includes("SameSite")) {
if (typeof value === "string") {
const needsSameSite =
value.includes("_GRECAPTCHA") || // Google reCAPTCHA
value.includes("hmt_id") || // hCaptcha
value.includes("cf_clearance") || // Cloudflare
value.includes("yandex") || // Yandex general
value.includes("smart-captcha") || // Yandex SmartCaptcha
value.includes("spravka"); // Yandex verification

if (needsSameSite && !value.includes("SameSite")) {
value += "; SameSite=None; Secure";
}
}
Expand Down Expand Up @@ -163,13 +206,18 @@ function enhanceNetworkRequests() {
}

/**
* Global declaration for reCAPTCHA config
* Global declarations for CAPTCHA systems
*/
declare global {
interface Window {
// Google reCAPTCHA config
___grecaptcha_cfg?: {
clients: Record<string, any>;
[key: string]: any;
};
// Yandex SmartCaptcha
smartCaptcha?: {
[key: string]: any;
};
}
}