[{"content":" For: beginners buying US stocks + broad-market ETFs (VOO / QQQ).\nHow to use this: You don\u0026rsquo;t need to read it all at once. Come back and look things up when you hit a term you don\u0026rsquo;t know. The ⭐ items are the core concepts to master first; the rest you can fill in gradually. Each entry roughly follows: what it is → how to use it → normal range / common pitfalls.\nThe basics: the asset classes you can buy Stock / Equity ⭐ A small slice of ownership in a company. Holding it gives you a small claim on the company\u0026rsquo;s future profits. What it\u0026rsquo;s worth in the long run ultimately depends on how much the company can earn.\nETF / Index Fund ⭐ An ETF (\u0026ldquo;exchange-traded fund\u0026rdquo;) trades like a stock — you can buy and sell it any time. An index fund is the most common kind: it doesn\u0026rsquo;t pick stocks, it just mechanically holds a basket of assets in proportion to a \u0026ldquo;list\u0026rdquo; (an index). Buy VOO and you own a tiny slice of each of the ~500 companies in the S\u0026amp;P 500; buy QQQ and you hold the ~100 names in the Nasdaq-100 (tech-heavy). The upside is diversification and low cost.\nBond Essentially \u0026ldquo;you lend money to a government or company, it pays you interest periodically and returns the principal at maturity.\u0026rdquo; Steadier than stocks, and usually lower-returning. When interest rates rise, the price of already-issued bonds falls (many people don\u0026rsquo;t know this).\nCash / Money Market The safest, barely volatile — but inflation slowly erodes its purchasing power over time. Its role isn\u0026rsquo;t to earn money, it\u0026rsquo;s to be your \u0026ldquo;ammunition\u0026rdquo; and \u0026ldquo;cushion.\u0026rdquo;\nReading a stock\u0026rsquo;s key metrics (valuation) Market Cap ⭐ A company\u0026rsquo;s total price tag = share price × total shares. Whether a company is \u0026ldquo;big\u0026rdquo; is judged by market cap, not share price. Common tiers: large-cap (\u0026gt;$10B), mid-cap, small-cap.\nShare price ≠ cheap or expensive (a key misconception) ⭐ A $500 stock isn\u0026rsquo;t necessarily \u0026ldquo;more expensive\u0026rdquo; than a $50 one. Share price is just \u0026ldquo;total value ÷ number of shares\u0026rdquo; — it has no direct relationship to whether the company is over- or undervalued. To judge cheap vs expensive, look at the valuation multiples below (like P/E), not the per-share price.\nEPS (Earnings Per Share) Net income ÷ total shares — \u0026ldquo;how much profit each share gets.\u0026rdquo; It\u0026rsquo;s the denominator of the P/E ratio and one of the most-watched numbers each earnings season.\nP/E Ratio ⭐ = Share price ÷ earnings per share. Intuitively: at the current level of earnings, how many years it takes to \u0026ldquo;earn back\u0026rdquo; the price you paid. A high P/E usually means the market expects fast future growth (or it may be overvalued); a low P/E may be cheap, or may signal the market isn\u0026rsquo;t optimistic.\nTTM P/E: uses the actual profit of the past 12 months (looking back). Forward P/E: uses forecast future profit (looking ahead). Reference: the S\u0026amp;P 500\u0026rsquo;s long-run historical average is roughly 15–20x. PEG Ratio = P/E ÷ earnings growth rate. Used to correct for \u0026ldquo;is a high P/E actually expensive or reasonable?\u0026rdquo; Rule of thumb: around 1 is reasonable, well above 1 may be pricey. (A rough indicator Peter Lynch favored — don\u0026rsquo;t treat it as an exact formula.)\nP/B (Price-to-Book) = Share price ÷ book value per share. More meaningful for \u0026ldquo;asset-heavy\u0026rdquo; businesses like banks and real estate; of little reference value for asset-light tech companies.\nP/S (Price-to-Sales) = Market cap ÷ revenue. Often used for growth companies that aren\u0026rsquo;t profitable yet (with no profit, you can\u0026rsquo;t compute a P/E).\nDividend Yield = Annual dividend per share ÷ share price. E.g. a $100 stock paying $3 a year yields 3%. Note: an absurdly high yield is sometimes an illusion created by a crashing price — not necessarily a good thing.\nRevenue / Net Income Revenue is \u0026ldquo;how much was sold\u0026rdquo; (top line); net income is \u0026ldquo;what\u0026rsquo;s actually earned at the end\u0026rdquo; (after all costs, expenses and taxes). Be wary of companies whose revenue grows fast but never turn a profit.\nFree Cash Flow (FCF) ⭐ = Cash generated by operations − the capital spending needed to maintain/expand. In plain terms, \u0026ldquo;the cash the company can truly spend freely.\u0026rdquo; Profit can be dressed up with accounting; cash flow is harder to fake, so many veterans weight it more heavily.\nROE (Return on Equity) = Net income ÷ shareholders\u0026rsquo; equity. Measures \u0026ldquo;for every $1 shareholders put in, how much the company earns in a year\u0026rdquo; — a key gauge of profit efficiency. Consistently 15%+ over the long run is usually considered excellent.\nMargins Gross margin = (revenue − cost) ÷ revenue; net margin = net income ÷ revenue. High and stable margins often indicate a \u0026ldquo;moat\u0026rdquo; (strong pricing power, little competition).\nReading an ETF / fund\u0026rsquo;s metrics Expense Ratio ⭐ The annual management fee a fund takes from the assets you hold, as a percentage. It looks tiny, but its impact under long-term compounding is huge.\nVOO is about 0.03%/yr, QQQ about 0.20%/yr. Intuition: a 1% annual fee can erode more than a fifth of your final return over 30 years. This is the first number to check when choosing a fund. AUM (Assets Under Management) The total assets a fund manages. Very small funds risk being closed down; mainstream broad-market funds (VOO / QQQ) are enormous, so no worries there.\nHoldings \u0026amp; Weights Exactly which companies a fund holds and at what proportions. Before buying, glance at the top-10 holdings — you\u0026rsquo;ll find many \u0026ldquo;different\u0026rdquo; tech ETFs have heavily overlapping top-10 holdings (the same few mega-caps), so buying several may not actually diversify you.\nTracking Error The deviation between an index fund\u0026rsquo;s actual performance and the index it tracks. Smaller is better — it means the fund \u0026ldquo;replicates\u0026rdquo; more precisely.\nPremium / Discount The gap between an ETF\u0026rsquo;s market price and its actual net asset value (NAV). Mainstream large ETFs hug their NAV; niche, obscure, or off-hours ETFs can show a clear premium/discount — effectively paying more / receiving less.\nLiquidity / Volume How much it trades each day. Good liquidity = small bid-ask spread, easy to fill; with an illiquid niche ETF, the spread alone can eat a meaningful chunk of your return.\nDistribution An ETF periodically passes the dividends its holdings pay through to you. VOO-type funds have a certain dividend; QQQ less so (growth stocks generally pay little).\nReturn and risk metrics (what decides whether you sleep at night) CAGR (Compound Annual Growth Rate) ⭐ Converts the total growth over a period into \u0026ldquo;the average compound growth per year.\u0026rdquo; It\u0026rsquo;s a geometric mean, not a simple \u0026ldquo;total return ÷ number of years\u0026rdquo; — the latter overstates it. E.g. up 60% over three years is a CAGR of about 17%, not 20%. (Why too high? Compounding: 20% a year would actually compound to +73% over three years, far past 60%; to land exactly on 60% you only need ~17% a year.) Why it matters: it compresses bumpy multi-year performance into one comparable annualized figure — the universal yardstick for comparing the long-term performance of different funds/strategies.\nTotal Return vs Price Return ⭐ Price return only counts how much the price/NAV rose; total return also includes the dividends received (assumed reinvested). Over the long run the gap is large — a substantial part of the S\u0026amp;P 500\u0026rsquo;s long-term return comes from reinvested dividends. When looking at a fund\u0026rsquo;s or index\u0026rsquo;s historical performance, look for the \u0026ldquo;Total Return\u0026rdquo; figure and don\u0026rsquo;t be misled by numbers that show price appreciation only.\nVolatility ⭐ How violently the price swings up and down, usually measured by standard deviation. High volatility ≠ certain loss, but it means a bumpier ride that tests your nerves more. QQQ\u0026rsquo;s volatility is clearly higher than VOO\u0026rsquo;s.\nBeta (β) ⭐ Measures how much an asset amplifies the swings of the whole market. The market itself = 1.0.\nβ \u0026gt; 1: swings more than the market (e.g. many tech stocks, QQQ). β \u0026lt; 1: steadier than the market (e.g. utility stocks). β ≈ 1: moves in step with the market (VOO is close to 1). Max Drawdown ⭐ The largest historical drop from a peak to a trough. It\u0026rsquo;s the key gauge of \u0026ldquo;how much pain you\u0026rsquo;d have to endure in the worst case.\u0026rdquo; A max drawdown of 50% means you might have to watch your account get cut in half. Check an asset\u0026rsquo;s historical max drawdown before buying, and ask yourself whether you can stomach it.\nSharpe Ratio = (return − risk-free rate) ÷ volatility. Measures \u0026ldquo;how much excess return you get for each unit of risk you take on.\u0026rdquo; Higher is better — a common way to compare the \u0026ldquo;bang for the buck\u0026rdquo; of different strategies.\nCorrelation ⭐ Whether two assets rise and fall together, ranging from −1 to +1.\nNear +1: highly synchronized (e.g. VOO and QQQ, both US stocks, rising and falling together). Near 0 or negative: independent or even opposite movements. Real diversification comes from holding assets with low correlation. Holding VOO + QQQ together — highly correlated — gives limited diversification. Trading and costs (quietly eating your money every day) Bid-Ask Spread ⭐ The gap between the buy price (bid) and the sell price (ask). That little slice where you\u0026rsquo;re \u0026ldquo;down the moment you buy\u0026rdquo; is the spread. For mainstream large stocks/ETFs it\u0026rsquo;s tiny; for obscure names it can be large.\nMarket vs Limit Order ⭐\nMarket order: fills immediately at the current best price — fast, but the price isn\u0026rsquo;t under your control (in thin liquidity it can fill at a terrible price). Limit order: you specify a price and it only fills at that price — price is controlled, but it may not fill. Beginner habit: unless you urgently need to fill, prefer limit orders. Slippage The gap between the price you expected and the price you actually got, common with large orders, sharp volatility, or thin liquidity.\nTax ⭐ An often-overlooked layer of cost. When you sell and realize a gain you usually owe capital gains tax, and dividends received may be withheld too. The general rule is the longer you hold, the friendlier the rate (many markets reward long-term holding), so frequent trading costs you not just spread and slippage but extra tax. Exact rates depend on your jurisdiction and account type — figure out your own tax situation before you start, because the impact on your take-home return is often bigger than you\u0026rsquo;d think.\nPortfolio and strategy (the layer that matters most) ⭐ Asset Allocation ⭐ How your money is split across stocks / bonds / cash. Research repeatedly shows: what mainly determines your long-term return and volatility is the allocation, not which individual stock you picked. This is the layer beginners should care about most yet most easily ignore.\nDiversification ⭐ \u0026ldquo;Don\u0026rsquo;t put all your eggs in one basket.\u0026rdquo; By holding multiple, low-correlation assets, you reduce the damage any single blow-up does to you. Note: buying a pile of highly correlated things (like several tech ETFs) is not real diversification.\nCompounding ⭐ Returns generating further returns, like a snowball. Its power comes from time — at the same annual return, the final result over 30 years vs 10 years is worlds apart.\nShortcut: the Rule of 72. Divide 72 by your annual return rate to estimate the years needed to double your principal. At 8% a year, ~9 years to double; at 4%, ~18 years. A handy tool for mentally gauging the power of compounding.\nDollar-Cost Averaging (DCA) ⭐ Investing a fixed amount at fixed intervals (e.g. buying a chunk of VOO every month), without trying to predict highs and lows. The benefit is averaging out your cost, avoiding \u0026ldquo;going all-in at the top,\u0026rdquo; and not letting emotion drive your timing.\nRebalancing After a while, the assets that rose most grow as a share of your portfolio, drifting away from your target allocation. Rebalancing means periodically selling a bit of what rose and topping up what lagged, pulling the proportions back to target. In essence, \u0026ldquo;passively selling high and buying low.\u0026rdquo;\nPosition Sizing How large a single asset is in your portfolio. However bullish you are on something, cap any single holding so that if it blows up it can\u0026rsquo;t drag down the whole.\nMacro factors (the tide that moves the whole market) Interest Rates / The Fed ⭐ The benchmark rate the Fed adjusts is one of the biggest variables affecting the stock market. Rough rule: hiking (money gets more expensive) is usually bearish for stocks, hitting growth/tech (QQQ) hardest; cutting is usually bullish. Because rates affect \u0026ldquo;what future money is worth discounted to today.\u0026rdquo;\nInflation / CPI ⭐ How fast prices rise, usually measured by CPI. Too-high inflation forces the Fed to hike, which then suppresses stocks. The market is very sensitive to the monthly CPI print.\nDon\u0026rsquo;t forget to compute the real return. Nominal return is the headline number; real return ≈ nominal return − inflation. If you made 5% in a year but inflation was 4%, your purchasing power actually grew only ~1%. To gauge whether an investment truly made you richer, look at the real return, not the headline.\nYield Curve The curve connecting the rates of government bonds of different maturities. When short-term rates exceed long-term (\u0026ldquo;inversion\u0026rdquo;), it\u0026rsquo;s often seen as an early warning of recession.\nDollar Index (DXY) The strength of the US dollar against a basket of currencies. A strengthening dollar often pressures emerging markets and commodities.\nLeverage and derivatives (high risk — understand before you touch) Margin ⭐ Borrowing from your broker to amplify your buying. It magnifies gains and losses; when losses get too big it triggers a \u0026ldquo;margin call / forced liquidation,\u0026rdquo; potentially selling you out at the very bottom. Use with caution as a beginner.\nLeveraged / Inverse ETF Decay ⭐ Products like TQQQ (3x long the Nasdaq) and SQQQ (3x short) target a fixed multiple of daily return. Because they re-lever every day, choppy back-and-forth markets create \u0026ldquo;volatility decay\u0026rdquo; — holding long term often underperforms the target you imagined, and you can lose even when the direction was right. They\u0026rsquo;re designed for short-term hedging/trading, not for buy-and-hold.\nOptions Contracts that give you the right to buy/sell an asset at a certain price (call / put). Usable for hedging or speculation — high leverage, complex mechanics. Strongly recommended to nail down all the basics above before touching them.\nOne-paragraph summary for beginners First, thoroughly understand the \u0026ldquo;Portfolio and strategy\u0026rdquo; section, plus the metrics expense ratio, max drawdown, correlation, and CAGR. Their impact on your long-term outcome far outweighs studying any single individual stock. Treat these as the \u0026ldquo;foundation,\u0026rdquo; and the rest of the terms as tools you look up when you need them.\nDisclaimer: this article is conceptual education and does not constitute investment advice.\n","permalink":"https://blog.lddi.net/en/posts/investing-concepts/","summary":"A concept map for beginners buying US stocks and broad-market ETFs — covering asset classes, valuation metrics, risk indicators and portfolio strategy, with the must-know core concepts flagged.","title":"Investing 101: The Core Concepts Behind Assets, Valuation, Risk and Portfolios"},{"content":" This is a record of lawful network experiments on a server you own, for learning and reference only. Please comply with the laws of your jurisdiction.\nThe previous post, VLESS, REALITY and CDN, covered the theory. This one gets hands-on: on a single VPS, we\u0026rsquo;ll bring up both REALITY (direct, no domain needed) and WS + CDN (hides the origin, needs a domain). Both run on Xray, and the core difference is only in streamSettings.\nPrerequisites An overseas VPS (Debian / Ubuntu here) with root access; Port 443 opened in the firewall / security group; The WS + CDN option also needs a domain and a Cloudflare account. First install Xray with the official script:\nbash -c \u0026#34;$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\u0026#34; @ install The config file lives at /usr/local/etc/xray/config.json; after editing, restart with systemctl restart xray.\nOption 1: VLESS + REALITY (direct, no domain needed) REALITY needs no domain or certificate — it\u0026rsquo;s the simplest, and a good fit for a fresh machine whose IP hasn\u0026rsquo;t been blocked yet.\nStep 1: Generate the keys and IDs\nxray uuid # generate a UUID (client identity) xray x25519 # generate a key pair: Private key / Public key openssl rand -hex 8 # generate a shortId Note down: UUID, Private key (for the server), Public key (for the client), and shortId.\nStep 2: Server config\n{ \u0026#34;inbounds\u0026#34;: [ { \u0026#34;listen\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;port\u0026#34;: 443, \u0026#34;protocol\u0026#34;: \u0026#34;vless\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;\u0026lt;UUID\u0026gt;\u0026#34;, \u0026#34;flow\u0026#34;: \u0026#34;xtls-rprx-vision\u0026#34; } ], \u0026#34;decryption\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;tcp\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;reality\u0026#34;, \u0026#34;realitySettings\u0026#34;: { \u0026#34;dest\u0026#34;: \u0026#34;www.microsoft.com:443\u0026#34;, \u0026#34;serverNames\u0026#34;: [\u0026#34;www.microsoft.com\u0026#34;], \u0026#34;privateKey\u0026#34;: \u0026#34;\u0026lt;Private key\u0026gt;\u0026#34;, \u0026#34;shortIds\u0026#34;: [\u0026#34;\u0026lt;shortId\u0026gt;\u0026#34;] } } } ], \u0026#34;outbounds\u0026#34;: [{ \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34; }] } What the key parameters mean:\ndecryption: none: VLESS doesn\u0026rsquo;t encrypt on its own, so this is always none (encryption is handled by REALITY/TLS); flow: xtls-rprx-vision: XTLS Vision flow control, which avoids the double-encryption overhead of \u0026ldquo;TLS inside TLS\u0026rdquo;; for REALITY / direct TLS only; dest / serverNames: the real website to \u0026ldquo;borrow\u0026rdquo;; the two must match. Pick a major site that actually exists, supports TLS 1.3, and isn\u0026rsquo;t blocked locally as the \u0026ldquo;front\u0026rdquo;; privateKey: the private half of the REALITY key pair, kept on the server; the matching Public key goes to the client; shortIds: client identifiers — leave empty \u0026quot;\u0026quot; or use the value generated above; the server can hold several to distinguish clients. Step 3: Key client parameters\nParameter Value Purpose Address / Port the VPS IP / 443 direct to the server, no domain involved UUID generated above client identity, must match the server flow xtls-rprx-vision the Vision flow control matching the server security reality enable REALITY SNI www.microsoft.com the \u0026ldquo;front\u0026rdquo; site impersonated in the handshake; must equal the server\u0026rsquo;s serverNames publicKey (pbk) the Public key from above pairs with the server\u0026rsquo;s private key to authenticate shortId (sid) generated above must be one of the server\u0026rsquo;s shortIds fingerprint (fp) chrome the simulated TLS fingerprint, making the handshake look like Chrome Import via a share link\nRather than filling everything in by hand, it\u0026rsquo;s more common to import a single vless:// link (v2rayN, v2rayNG, NekoBox, etc. all support \u0026ldquo;import from clipboard\u0026rdquo;). The link format for a REALITY node:\nvless://\u0026lt;UUID\u0026gt;@\u0026lt;VPS-IP\u0026gt;:443?encryption=none\u0026amp;flow=xtls-rprx-vision\u0026amp;security=reality\u0026amp;sni=www.microsoft.com\u0026amp;fp=chrome\u0026amp;pbk=\u0026lt;Public key\u0026gt;\u0026amp;sid=\u0026lt;shortId\u0026gt;\u0026amp;type=tcp#REALITY Each parameter after ? maps to a row in the table above, and the text after # is the node label. Restart with systemctl restart xray, import it, and you\u0026rsquo;re connected.\nOption 2: VLESS + WS + CDN (hides the origin, needs a domain) When the machine\u0026rsquo;s IP is prone to being blocked, use Cloudflare to hide the origin.\nThis option adds one component over REALITY: Nginx. It\u0026rsquo;s the most widely used web server / reverse proxy, and here it does two jobs:\nServes HTTPS with a certificate on port 443 (the CDN requires the origin to be valid HTTPS, while Xray\u0026rsquo;s WS is just a bare WebSocket); Reverse-proxies only the agreed secret path (e.g. /mypath) to the local Xray, and returns an ordinary web page on every other path to disguise the server as a normal website. Nginx needs you to provide the certificate yourself. But since we\u0026rsquo;re already behind Cloudflare, the easiest route is Cloudflare\u0026rsquo;s free Origin Certificate — issued by Cloudflare, valid for up to 15 years, and only needs to be trusted by the CDN.\nStep 1: Cloudflare DNS + Origin Certificate\nPoint the domain\u0026rsquo;s A record at the VPS IP and enable the orange cloud (proxied); Set the SSL/TLS mode to Full (strict); Under SSL/TLS → Origin Server → Create Certificate, generate a certificate and save the cert and key to /etc/ssl/cf-origin.pem and /etc/ssl/cf-origin.key. If you\u0026rsquo;d rather not use the Origin Certificate, you can issue a Let\u0026rsquo;s Encrypt certificate with acme.sh via the Cloudflare DNS API; the Nginx config is the same afterward.\nStep 2: Xray listening on a local WS\n{ \u0026#34;inbounds\u0026#34;: [ { \u0026#34;listen\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;port\u0026#34;: 10000, \u0026#34;protocol\u0026#34;: \u0026#34;vless\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [{ \u0026#34;id\u0026#34;: \u0026#34;\u0026lt;UUID\u0026gt;\u0026#34; }], \u0026#34;decryption\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;ws\u0026#34;, \u0026#34;wsSettings\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;/mypath\u0026#34; } } } ], \u0026#34;outbounds\u0026#34;: [{ \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34; }] } Note the WS option needs no flow (Vision is only for REALITY / direct TLS).\nStep 3: Nginx HTTPS + reverse proxy\n/etc/nginx/conf.d/proxy.conf:\nserver { listen 443 ssl; http2 on; server_name your.domain.com; ssl_certificate /etc/ssl/cf-origin.pem; ssl_certificate_key /etc/ssl/cf-origin.key; # reverse-proxy the secret path to the local Xray location /mypath { proxy_pass http://127.0.0.1:10000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # WebSocket upgrade proxy_set_header Connection \u0026#34;upgrade\u0026#34;; # WebSocket upgrade proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # everything else returns a plain page as disguise location / { return 200 \u0026#34;hello\u0026#34;; } } The easiest thing to miss here is the Upgrade / Connection \u0026quot;upgrade\u0026quot; headers — without them the WebSocket never completes its handshake; Nginx requires you to add them explicitly when proxying WebSocket. Run nginx -t to check the syntax, then systemctl restart nginx.\nStep 4: Key client parameters\nParameter Value Purpose Address the domain (or a Cloudflare preferred IP) you connect to a Cloudflare node, not the origin Port 443 the CDN\u0026rsquo;s public HTTPS port UUID matches the server client identity security tls, SNI = the domain standard HTTPS between you and the CDN network ws, path = /mypath WebSocket transport; the path must match the server and Nginx exactly host the domain the WS Host header; required when using a preferred IP, since the CDN uses it to decide which site to route to Import via a share link\nThe vless:// link format for a WS + CDN node:\nvless://\u0026lt;UUID\u0026gt;@\u0026lt;domain-or-preferred-IP\u0026gt;:443?encryption=none\u0026amp;security=tls\u0026amp;sni=\u0026lt;domain\u0026gt;\u0026amp;type=ws\u0026amp;host=\u0026lt;domain\u0026gt;\u0026amp;path=%2Fmypath#WS-CDN Note that path must be URL-encoded in the link: /mypath becomes %2Fmypath. The WS option carries no flow (Vision is only for REALITY / direct TLS).\nVerifying and troubleshooting systemctl status xray nginx # are both services running? journalctl -u xray -e # check Xray error logs nginx -t # check Nginx config syntax ss -tlnp | grep -E \u0026#39;443|10000\u0026#39; # are the ports listening? Common pitfalls:\nREALITY won\u0026rsquo;t connect: usually the client\u0026rsquo;s publicKey / shortId / SNI don\u0026rsquo;t match the server. WS + CDN 502 / handshake failure: check that Nginx has the Upgrade / Connection headers, that the path matches Xray exactly, and that Cloudflare is proxied (orange cloud) with SSL mode Full (strict). Connects but no traffic: confirm both the VPS firewall and the cloud provider\u0026rsquo;s security group allow 443. Summary The Xray config differs between the two options almost only in streamSettings: REALITY uses tcp + reality, CDN uses ws wrapped in a layer of Nginx/CDN TLS; New machine, want speed → start with REALITY; IP being targeted, want to hide the origin → switch to WS + CDN; It\u0026rsquo;s worth setting up both and switching as the network conditions demand — which lines up exactly with the choice from the previous post. ","permalink":"https://blog.lddi.net/en/posts/vps-vless-setup/","summary":"A follow-up to the concepts post — this time we actually stand up both REALITY and WS + CDN on a single VPS, covering only the key steps and common pitfalls.","title":"Setting Up VLESS + REALITY and VLESS + WS + CDN"},{"content":" This article explains the design ideas behind open-source proxy protocols from a technical angle. It is for learning and lawful network research only — please comply with the laws of your jurisdiction.\nAn overlooked premise: the fight is about \u0026ldquo;detection\u0026rdquo;, not \u0026ldquo;encryption\u0026rdquo; Many people assume the key to a proxy is \u0026ldquo;encrypting the traffic\u0026rdquo;. But HTTPS already encrypts your content. The real difficulty is this: censorship systems (DPI, deep packet inspection) don\u0026rsquo;t need to decrypt your content at all — as long as they can recognize that \u0026ldquo;this is a proxy connection\u0026rdquo;, they can block it.\nSo the evolution of proxy protocols over the years has had only one main thread: make your traffic look indistinguishable from normal HTTPS, and ideally defeat active probing too. Grasp this thread, and VLESS, REALITY and CDN all fall into place.\nVLESS: a transport protocol built by subtraction VLESS is the core transport protocol of the Xray (Project X) project — think of it as the \u0026ldquo;lightweight successor\u0026rdquo; to the older VMess.\nIts most counter-intuitive trait: VLESS itself does not encrypt.\nVMess carried its own encryption and a time-based authentication scheme (alterID). That added overhead, and the encrypted traffic still had statistically detectable \u0026ldquo;fingerprints\u0026rdquo;. VLESS hands encryption entirely to the transport-layer TLS, and only uses a UUID for identity. The result is lighter, faster, and with fewer features to detect. The trade-off: VLESS is almost always paired with TLS (VLESS + TLS). With XTLS Vision flow control on top, it even avoids the double-encryption overhead of \u0026ldquo;TLS inside TLS\u0026rdquo;.\nIn one line: VLESS handles \u0026ldquo;transport\u0026rdquo;, TLS handles \u0026ldquo;looking like HTTPS\u0026rdquo;.\nREALITY: borrowing someone else\u0026rsquo;s storefront VLESS + TLS sounds perfect, but the TLS layer has a long-standing headache — certificates and domains:\nYou need your own domain and certificate; The SNI and certificate exposed during the TLS handshake reveal \u0026ldquo;this server is running a self-hosted service\u0026rdquo;; A censor can run active probing: connect to your port directly, and if the certificate looks suspicious or there\u0026rsquo;s no real website behind it, flag it as a proxy and block it. REALITY\u0026rsquo;s idea is clever: stop using your own certificate, and instead \u0026ldquo;borrow\u0026rdquo; the handshake of a real, popular website.\nRoughly how it works:\nWhen the client initiates the handshake, it puts a real, well-known site (e.g. www.microsoft.com) in the SNI; A client holding the correct key is recognized by the server and routed through the proxy; For an active prober with no key, the server transparently forwards it to that real website — the prober receives Microsoft\u0026rsquo;s genuine certificate and real page, with nothing out of place. The payoff: no domain or certificate of your own needed; your TLS fingerprint is that of a real major site; and active probing can\u0026rsquo;t break through, because what it reaches is the real website.\nThe key part of the server config looks like this (Xray):\n{ \u0026#34;protocol\u0026#34;: \u0026#34;vless\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [{ \u0026#34;id\u0026#34;: \u0026#34;your-UUID\u0026#34;, \u0026#34;flow\u0026#34;: \u0026#34;xtls-rprx-vision\u0026#34; }], \u0026#34;decryption\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;tcp\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;reality\u0026#34;, \u0026#34;realitySettings\u0026#34;: { \u0026#34;dest\u0026#34;: \u0026#34;www.microsoft.com:443\u0026#34;, \u0026#34;serverNames\u0026#34;: [\u0026#34;www.microsoft.com\u0026#34;], \u0026#34;privateKey\u0026#34;: \u0026#34;server private key\u0026#34;, \u0026#34;shortIds\u0026#34;: [\u0026#34;\u0026#34;] } } } dest / serverNames are the \u0026ldquo;borrowed\u0026rdquo; target site; privateKey pairs with the client\u0026rsquo;s public key to complete authentication.\nCDN: hiding your origin IP REALITY solves \u0026ldquo;traffic fingerprinting\u0026rdquo; and \u0026ldquo;active probing\u0026rdquo;, but one weak spot remains: your server\u0026rsquo;s IP is exposed via a direct connection. Once that IP is targeted, it can simply be blocked by IP.\nA CDN (such as Cloudflare) offers another route:\nThe client connects to the CDN\u0026rsquo;s IP, and the CDN relays traffic back to your server; The censor only sees the CDN\u0026rsquo;s huge pool of shared IPs, which can\u0026rsquo;t be blocked wholesale (doing so would take down countless legitimate sites); Your real origin IP stays hidden behind the CDN. A CDN setup usually looks like this: VLESS + WebSocket + TLS, because CDNs primarily proxy HTTP / WebSocket traffic.\nOne crucial realization here: REALITY and CDN are essentially mutually exclusive. A CDN terminates (decrypts) TLS on its side, whereas REALITY requires the genuine TLS handshake to reach your own server untouched. So they are \u0026ldquo;two different routes\u0026rdquo;, not something you stack.\nHow to choose: REALITY vs CDN Dimension VLESS + REALITY VLESS + WS + CDN Domain / certificate Not needed Domain needed (cert can come from the CDN) Resistance to active probing Strong (probes see a real site) Moderate Origin IP Exposed directly, can be IP-blocked Hidden behind CDN, harder to block Latency / speed Direct, low latency One extra hop, higher latency Privacy Traffic doesn\u0026rsquo;t pass a third party CDN can see it (it terminates TLS) Quick rule of thumb:\nWant low latency and strong anti-probing, and don\u0026rsquo;t mind rotating IPs → choose REALITY; Origin IP gets blocked easily, want to hide the server → choose CDN (WS + TLS); Advanced users run both and switch depending on the network environment. Summary The core tension of a proxy is not being detected, not encryption; VLESS subtracts: it hands encryption to TLS and only does lightweight transport; REALITY uses \u0026ldquo;impersonating a real site\u0026rsquo;s handshake\u0026rdquo; to solve the certificate/domain and active-probing problems; CDN takes a different angle, hiding your origin behind shared IPs at the cost of latency and privacy. None of the three replaces the others — each fills in a piece of the puzzle against \u0026ldquo;detection\u0026rdquo; and \u0026ldquo;blocking\u0026rdquo;.\n","permalink":"https://blog.lddi.net/en/posts/net-proxy/","summary":"Starting from one core idea — evading detection rather than encryption — this post explains what VLESS, VLESS + REALITY and CDN each solve, and how to choose between them.","title":"VLESS, REALITY and CDN: Three Pieces of the Modern Proxy Puzzle"},{"content":"About me I\u0026rsquo;m Di Li, a game developer. I enjoy digging into all kinds of tech and keep a side interest in finance and investing. Rather than letting what I learn pile up in my head, I\u0026rsquo;d rather write it down — putting something into clear words is usually how I find out whether I actually understood it.\nWhat I write about Tech: game development, networking, backend, and notes from the tools I tinker with; Finance: thoughts and notes on investing; Tutorials: end-to-end steps to get something working — for my future self, and for you to follow along. I don\u0026rsquo;t aim for quantity, just for getting the key points across.\nWhy I write Partly for myself: written notes are far more reliable than memory when I come back to them later. Partly for you — if a post happens to save you a few hours, that\u0026rsquo;s the best thing it can do.\n","permalink":"https://blog.lddi.net/en/about/","summary":"About me and this blog","title":"About"},{"content":"When you set up a fresh machine — a dev box or a server — and try to clone, pull or push your GitHub repos, you often get stuck on authentication. First, get clear on when authentication is actually needed:\nRead-only clone of a public repo → no auth needed, just pull; Accessing a private repo (clone / pull / push) → auth required; Pushing to any repo (even a public one) → auth required too. In other words, apart from pulling public repos, any privileged operation on a repo needs an \u0026ldquo;identity\u0026rdquo; first. Set it up once, and the machine can clone / pull / push normally afterward.\nThe main idea: there are two routes to an identity — SSH keys or a token (PAT) — and the difference is \u0026ldquo;how many doors this key opens, and what it can do\u0026rdquo;.\nHow public/private key authentication works Both SSH options below rest on a key pair, so let\u0026rsquo;s get the verification flow straight first:\nPrivate key: stays on your machine (in ~/.ssh/) and is never sent anywhere; Public key: can be shared, and you register it with GitHub. They are asymmetric — a signature made with the private key can only be verified by the matching public key, and you can\u0026rsquo;t derive the private key from the public one. The flow goes roughly like this:\nYou register the public key with GitHub ahead of time (account SSH keys, or a repo\u0026rsquo;s Deploy keys); On connecting, your machine starts an SSH session claiming \u0026ldquo;I hold the private key matching a certain public key\u0026rdquo;; GitHub uses the registered public key to issue a random challenge; Your machine signs the challenge with the private key and sends the result back; GitHub verifies that signature with the public key — if it checks out, you\u0026rsquo;ve proven you hold the matching private key, your identity is established, and you\u0026rsquo;re let in. your machine GitHub │ ① I hold the private key for ... │ │ ───────────────────────────────▶ │ │ ② random challenge │ │ ◀─────────────────────────────── │ │ ③ sign the challenge with the │ │ PRIVATE key, send it back │ │ ───────────────────────────────▶ │ │ ④ verify with registered PUBLIC │ │ key → access granted │ The key point: the private key never leaves your machine — all that travels over the network is \u0026ldquo;proof computed with the private key\u0026rdquo;. So even if the whole exchange is intercepted, the private key can\u0026rsquo;t be stolen. That\u0026rsquo;s why the public key can be shared freely while the private key must stay secret.\nOption 1: SSH key (account-level, most general) A key tied to your GitHub account works for all your repos and all of clone / pull / push — ideal for a dev machine you use regularly.\n① Generate a key (just press Enter through the prompts):\nssh-keygen -t ed25519 -C \u0026#34;my-laptop\u0026#34; It asks for a save path (Enter for the default ~/.ssh/id_ed25519) and a passphrase (Enter for none). It produces two files: id_ed25519 (the private key, keep it secret) and id_ed25519.pub (the public key).\n-t ed25519: key type — shorter and more secure than the old RSA, the current recommendation; -C \u0026quot;my-laptop\u0026quot;: a comment/label, purely to help you recognize it later; no effect on function. ② Add the public key to your account:\ncat ~/.ssh/id_ed25519.pub # copy this GitHub → Settings → SSH and GPG keys → New SSH key → paste.\n③ Use SSH URLs (a default-named key is picked up by SSH automatically, no extra config):\ngit clone git@github.com:ldddi/your-repo.git ssh -T git@github.com # verify: seeing \u0026#34;Hi ldddi!\u0026#34; means it works Pro: set up once, covers all your repos and all operations; Con: broad access — if the machine is compromised, all your repos are exposed. So on servers, the read-only Deploy Key below is a better fit. Option 2: Deploy Key (bound to a single repo — best for servers/CI) An SSH key scoped to one repo, and one you can make read-only. Ideal for a VPS pulling one project to deploy — minimal access, so even if the machine is breached, only that one repo\u0026rsquo;s read is affected.\n① Generate it on that machine (again, just press Enter):\nssh-keygen -t ed25519 -C \u0026#34;deploy-my-blog\u0026#34; ② Add the public key to the \u0026ldquo;repo\u0026rdquo; (not the account): GitHub → open the repo → Settings → Deploy keys → Add deploy key → paste ~/.ssh/id_ed25519.pub. For pull-only, don\u0026rsquo;t tick \u0026ldquo;Allow write access\u0026rdquo; (read-only is safest).\n③ Clone / switch the remote to the SSH URL:\ngit clone git@github.com:ldddi/my-blog.git # already cloned over https? switch the remote: git remote set-url origin git@github.com:ldddi/my-blog.git Advanced: one machine pulling multiple private repos A Deploy Key binds to a single repo, and the default name id_ed25519 only exists once per machine. So for multiple repos, generate a separate key per repo with -f to give each a different filename:\nssh-keygen -t ed25519 -C \u0026#34;deploy-blog\u0026#34; -f ~/.ssh/key-blog -N \u0026#34;\u0026#34; ssh-keygen -t ed25519 -C \u0026#34;deploy-repoA\u0026#34; -f ~/.ssh/key-repoA -N \u0026#34;\u0026#34; (Here -f sets the filename and -N \u0026quot;\u0026quot; sets an empty passphrase — exactly so you can keep multiple keys apart and avoid interactive prompts.)\nBut SSH won\u0026rsquo;t use custom-named keys on its own (it only looks for default names like id_ed25519). So on this machine (not GitHub), edit ~/.ssh/config to tell it \u0026ldquo;which key for which repo\u0026rdquo;:\n# This file lives on the machine that pulls: ~/.ssh/config Host github-blog # a custom alias, name it anything HostName github.com User git IdentityFile ~/.ssh/key-blog # this alias uses this private key IdentitiesOnly yes Host github-repoA HostName github.com User git IdentityFile ~/.ssh/key-repoA IdentitiesOnly yes Host github-blog: an alias — since both repos are on github.com, the alias is how you pick which key to use; HostName / User git: it still actually connects to github.com with the fixed username git; IdentityFile: which private key this alias uses; IdentitiesOnly yes: use only this key, don\u0026rsquo;t try the machine\u0026rsquo;s other keys (avoids wrong-key failures). When cloning, replace github.com in the URL with your alias:\ngit clone git@github-blog:ldddi/my-blog.git # note: github-blog, not github.com For a single repo, just use the default name id_ed25519 — SSH uses it automatically and you don\u0026rsquo;t need this config at all.\nOption 3: Personal Access Token (PAT, over HTTPS) If you\u0026rsquo;d rather not use SSH, or you\u0026rsquo;re in CI, use a token over HTTPS:\nGitHub → Settings → Developer settings → Fine-grained token, scope it to specific repos with the permissions you need (Contents: Read for pull only, Read and write for push); Clone: git clone https://\u0026lt;TOKEN\u0026gt;@github.com/ldddi/your-repo.git Pro: permissions can be as fine as \u0026ldquo;read-only on one repo\u0026rdquo;; good for CI and pure-HTTPS setups; Con: tokens expire, so they need safe storage and periodic rotation. How to choose Method Can access Can do Best for Account SSH key all your repos clone / pull / push your own dev machine Deploy Key a single repo read-only (write optional) server / CI pulling one repo PAT (HTTPS) scopable per repo per granted permission CI, HTTPS environments Summary Read-only cloning of public repos needs no auth; private repos, and any push, do; Your own dev machine → account SSH key, set up once, covers every repo and operation; A server pulling a single repo to deploy → read-only Deploy Key, minimal access and safest; CI / HTTPS → PAT. ","permalink":"https://blog.lddi.net/en/posts/github-machine-access/","summary":"A fresh machine wants to clone / pull / push your repos but gets stuck on auth. When auth is needed, how to set up SSH keys and tokens, and which to use on a server.","title":"How to Let a Machine Access Your GitHub Repos"},{"content":"The first time you see Edge Certificates, Client Certificates and Origin Server in the Cloudflare dashboard, it\u0026rsquo;s easy to get lost. But once you understand what Cloudflare actually does between you and your visitors, all three fall into place.\nFirst: what Cloudflare does in the middle Cloudflare is essentially a CDN + reverse proxy. When you put your domain behind Cloudflare and turn on the \u0026ldquo;orange cloud\u0026rdquo;, one key thing happens: your domain\u0026rsquo;s DNS no longer resolves to your server — it points to Cloudflare\u0026rsquo;s IPs.\nSo a visitor\u0026rsquo;s request goes from \u0026ldquo;direct\u0026rdquo; to \u0026ldquo;relayed\u0026rdquo;:\nvisitor ──→ Cloudflare edge node (the data center nearest them) ──→ your origin server This middle layer brings the usual CDN benefits:\nNearby access + caching: visitors connect to the closest edge node, and static content is served straight from cache — faster; Hiding and protecting the origin: visitors only ever see Cloudflare\u0026rsquo;s IPs; your real server IP stays hidden, blocking DDoS and port scanning; Edge protection: WAF, rate limiting and bot filtering all happen at the edge. The trade-off: Cloudflare has to sit in the middle, decrypt the visitor\u0026rsquo;s HTTPS, then forward it to you. Because of this extra hop, HTTPS is no longer one end-to-end connection — it\u0026rsquo;s split into two, each with its own TLS handshake and its own certificate:\nvisitor browser ──TLS①── Cloudflare edge ──TLS②── your origin (Nginx) Edge cert Origin cert TLS①: the visitor only handshakes with Cloudflare, and sees the Edge certificate; TLS②: Cloudflare separately handshakes with your origin, using the Origin certificate; and that SSL/TLS mode in the dashboard (Flexible / Full / Full strict) defines exactly \u0026ldquo;how the second hop is encrypted, and whether the origin cert is verified\u0026rdquo;. Hold on to this one idea — a single HTTPS connection split into two hops — and the three certificates become clear.\nEdge Certificates These cover TLS①: visitor browser ⇄ Cloudflare.\nThey live on Cloudflare\u0026rsquo;s edge nodes — the lock and certificate a visitor sees in the address bar is this one; By default Cloudflare issues and renews them for free (Universal SSL); you don\u0026rsquo;t have to do anything; They are publicly trusted certs (signed by a CA browsers trust), because they face visitors directly. The HTTPS your visitors see on blog.lddi.net is the Edge certificate at work.\nOrigin Server Certificates These cover TLS②: Cloudflare ⇄ your origin server.\nIssued by Cloudflare, but installed on your own server (Nginx); Key trait: they only need to be trusted by Cloudflare (it\u0026rsquo;s fine that browsers don\u0026rsquo;t trust them, since visitors never connect to the origin directly); valid for up to 15 years; free; Used together with the Full (strict) SSL/TLS mode — that mode verifies the origin certificate\u0026rsquo;s validity, so the origin must have one. This is exactly the /etc/ssl/cloudflare/lddi.net.pem in your VPS\u0026rsquo;s Nginx config — it\u0026rsquo;s the Origin certificate.\nClient Certificates This one is a different dimension — don\u0026rsquo;t mix it up with the two above. It\u0026rsquo;s for mTLS (mutual TLS), and it verifies who is connecting.\nNormal HTTPS only verifies the server\u0026rsquo;s identity (proving \u0026ldquo;you really did reach this site\u0026rdquo;); mTLS additionally requires the client to present a certificate, proving \u0026ldquo;you are an authorized visitor\u0026rdquo;; Cloudflare can act as a private CA to issue client certificates and hand them to authorized devices/users; once mTLS is enabled, any request without a valid client certificate is rejected outright; Typical uses: internal APIs, admin systems, mobile app backends — only letting specific devices in and shutting everyone else out. So a Client certificate isn\u0026rsquo;t for \u0026ldquo;encrypting the channel\u0026rdquo; — it\u0026rsquo;s for \u0026ldquo;identifying who\u0026rsquo;s knocking\u0026rdquo;.\nOne table to tell them apart Certificate Lives where Covers / role Whose identity Issued by Edge Cloudflare edge visitor ⇄ Cloudflare (encryption) server (to the visitor) Cloudflare (Universal) / your own Origin Server your origin Nginx Cloudflare ⇄ origin (encryption) origin (to Cloudflare) Cloudflare Origin CA Client the client device mutual auth (who you are) the client / visitor Cloudflare Client CA Summary Edge and Origin are the two \u0026ldquo;server certificates\u0026rdquo; for the two hops a single HTTPS connection is split into by Cloudflare — one facing the visitor, one facing the origin; Client is a separate thing — during the handshake it verifies the client\u0026rsquo;s identity instead, used for mTLS access control; For everyday self-hosting, the first two matter most: the visitor hop (Edge) is handled automatically by Cloudflare, while the origin hop (Origin) needs a cert installed on your server plus the mode set to Full (strict). ","permalink":"https://blog.lddi.net/en/posts/cloudflare-certificates/","summary":"Using one idea — a single HTTPS connection split into two hops by Cloudflare — to explain what Edge, Origin Server and Client certificates each do.","title":"Cloudflare's Three Certificate Types: Edge, Client, Origin Server"}]