MySQL derived query with random order
If you want the query to return just 1 row, a zone with a random proxy (chosen from the associated ones), then it's easy to fix the query:

SELECT z.*, ps.* 
FROM Zones AS z    
  LEFT JOIN ProxyServers AS ps 
  ON ps.ProxyType = z.ProxyType 
-- WHERE &lt;some condition to choose from some zones or just one&gt;
ORDER BY RAND() 
LIMIT 1 ;


or even better:

SELECT z.*, ps.* 
FROM 
    ( SELECT *
      FROM Zones
      ORDER BY ZoneID DESC
      LIMIT 1
    ) AS z    
  LEFT JOIN ProxyServers AS ps 
  ON ps.ProxyType = z.ProxyType 
ORDER BY RAND() 
LIMIT 1 ;




If you want multiple or all the zones, each one with a randomly chosen proxy server, it's really not trivial to solve, due to the way that MySQL executes subqueries (in ON and WHERE clauses). 

In short, the subqueries (the ON condition in your case) is executed for each and every combination of z and ps. Sometimes the randomly chosen ProxyID matches the ps.ProxyID, sometimes it doesn't. Therefore, for each zone, you may get 0 matches, 1, 2 or more, which is exactly what you see in the results.
See previous answers in similar issues:


How can this return more than 1 result?  
Problem with MySQL subquery




Writing a query that behaves as expected - and return 1 row for each zone - it really hard because the values of RAND() are not found previously stored in a table but provided during run time.

A work around would be to abuse two other non-standard MySQL "features". First, that subqueries allow ORDER BY without LIMIT, which is normally redundant. Second, that in GROUP BY queries, it is allowed to have expressions in the SELECT list which are not aggregates and are not in the GROUP BY list. This is also against the standard and often leads to unexpected results for poorly written queries. 

Combining these two ill-behaving features, we can have a monster:

SELECT g.*
FROM
  ( SELECT z.*, 
           ps.ProxyID, ps.ProxyIP, zs.ProxyPort, ps.Enabled 
    FROM Zones AS z    
      LEFT JOIN ProxyServers AS ps 
      ON ps.ProxyType = z.ProxyType 
    ORDER BY z.ZoneID, RAND() 
  ) AS g
GROUP BY ZoneID ;


It's certainly not guaranteed to work, as recent or future versions of MySQL may or do detect the ill behaviour and may either remove the redundant ORDER BY killing the wanted functionality or may throw an error due to the non-standard GROUP BY clause.